I'm doing an exercise now where I'm looking for all of the zeros in an array.
The input is:
numbers = [1, 3, 500, 200, 4000, 3000, 10000, 90, 20, 500000]
I want to sort them into a hash by the number of zeros. The expected output is:
expected = {0=>[1, 3], 2=>[500, 200], 3=>[4000, 3000], 4=>[10000], 1=>[90, 20], 5=>[500000]}
I have the structure built but I'm not sure how to count the number of zeros:
grouped = Hash.new {|hash, key| hash[key] = []}
numbers.each do |num|
grouped[num] << num
end
EDITED for clarity: Any advice would be appreciated. Also, a lot of the advice I read on this recommended converting the array of integers to a string in order to solve the problem. Is there a way to count the number of digits (not just zeros) without converting the array to a string? The expected output in this case would look like:
expected = {1=>[1, 3], 2=>[90, 20], 3=>[500, 200], 4=>[4000, 3000], 5=>[10000], 6=>[500000]
Thanks in advance.
Like many transformations you'll want to do, this one's found in Enumerable .
Grouping by number of digits:
grouped = numbers.group_by { |n| Math.log10(n).to_i + 1 }
# => {1=>[1, 3], 3=>[500, 200], 4=>[4000, 3000], 5=>[10000], 2=>[90, 20], 6=>[500000]}
Grouping by number of zeroes:
grouped = numbers.group_by { |n| n.to_s.match(/0+$/) ? $&.length : 0 }
# => {0=>[1, 3], 2=>[500, 200], 3=>[4000, 3000], 4=>[10000], 1=>[90, 20], 5=>[500000]}
The group_by
method is a handy way to convert an Array to a Hash with things organized into pigeon-holes.
I wound up using
grouped = Hash.new {|hash, key| hash[key] = []}
numbers.each do |num|
grouped[num.to_s.count('0')] << num
end
but I really liked the variation in responses. I didn't realize there were so many ways to go about this. Thank you everyone.
Group by floor of log base 10?
1.9.3-p484 :014 > numbers.each {|n| grouped[Math.log10(n).floor] << n}
=> [1, 3, 500, 200, 4000, 3000, 10000, 90, 20, 500000]
1.9.3-p484 :016 > grouped
=> {0=>[1, 3], 2=>[500, 200], 3=>[4000, 3000], 4=>[10000], 1=>[90, 20], 5=>[500000]}
Or try 1 + Math.log10(n).floor
if you need the keys to be the actual number of digits.
If you wish to group non-negative integers by the number of zero digits they contain, you can do this:
def nbr_zeroes(n)
return 1 if n == 0
m = n
i = 0
while m > 0
i += 1 if m % 10 == 0
m /= 10
end
i
end
numbers = [1, 3, 500, 200, 4000, 3000, 10000, 90, 20, 500000]
numbers.group_by { |i| nbr_zeroes(i) }
#=> { 0=>[1, 3], 2=>[500, 200], 3=>[4000, 3000], 4=>[10000] }
numbers = [100000, 100001, 304070, 3500040, 314073, 2000, 314873, 0]
numbers.group_by { |i| nbr_zeroes(i) }
#=> { 5=>[100000], 4=>[100001, 3500040], 3=>[304070, 2000],
# 1=>[314073, 0], 0=>[314873] }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.