Reputation: 25267
Lets say that I have a number of "things", for instance 7
.
But I can store this "things" in groups of maximum "2" units. So I would need to do something like this:
7 ----> [2, 2, 2, 1]
The obvious method if to simply make a loop through it
def decompose(qty, group_max)
ret = []
while qty > 0
if qty < group_max
ret.push qty
qty = 0
else
ret.push group_max
qty -= group_max
end
end
ret
end
decompose 7, 2
While this works... it is not really ellegant. I was wondering if maybe there is a method in the integer or the array structure that I can use to improve this code.
I find cleaner to do things like
myarray.map {|x| ... }
and I was wondering if there was something similar that might help me with this.
Upvotes: 2
Views: 356
Reputation: 110675
def decompose(n, grp_size)
nbr_groups, remainder = n.divmod(grp_size)
[grp_size]*nbr_groups << remainder
end
decompose(23, 3)
#=> [3, 3, 3, 3, 3, 3, 3, 2]
Upvotes: 0
Reputation: 114178
Another way to skin the cat:
Lets say that I have a number of "things", for instance 7.
Let's use an array to represent that, each nil
is a "thing":
Array.new(7)
#=> [nil, nil, nil, nil, nil, nil, nil]
But I can store this "things" in groups of maximum "2" units:
each_slice
can do that:
Array.new(7).each_slice(2).to_a
#=> [[nil, nil], [nil, nil], [nil, nil], [nil]]
To get the number of "things" in each group:
Array.new(7).each_slice(2).map(&:length)
#=> [2, 2, 2, 1]
Upvotes: 1
Reputation: 80065
divmod
anyone?
qty = 15 # say
group_size = 2
d, r = qty.divmod(group_size)
Array.new(d, group_size) << r # => [2, 2, 2, 2, 2, 2, 2, 1]
Upvotes: 3
Reputation: 121000
val, max = 8, 3
([max] * (val / max)).tap do |arr|
arr << val % max unless (val % max).zero?
end
#⇒ [3, 3, 2]
val, max = 7, 2
([max] * (val / max)).tap do |arr|
arr << val % max unless (val % max).zero?
end
#⇒ [2, 2, 2, 1]
or even:
([max] * (val / max) + [val % max]).reject &:zero?
Upvotes: 2
Reputation: 30056
I'd take advantage of the Array constructor: first paramter the number of elements, second parameter their value.
def decompose(qty, group_max)
result = Array.new(qty / group_max, group_max)
remainder = qty % group_max
remainder == 0 ? result : result.push(remainder)
end
decompose(7, 2)
=> [2, 2, 2, 1]
A one line solution
def decompose(qty, group_max)
(Array.new(qty / group_max, group_max) + [qty % group_max]).reject(&:zero?)
end
Upvotes: 2
Reputation: 22217
def decompose(qty, group_max)
q, r = qty.divmod(group_max)
(Array.new(q) { group_max }) + (r > 0 ? [r] : [])
end
Upvotes: 3
Reputation: 4920
You can do this as:
qty = 15 # say
group_size = 2
count_of_groups = qty / group_size
result = [group_size] * count_of_groups
remaining = qty % group_size
result += [remaining] if remaining != 0
result # [2, 2, 2, 2, 2, 2, 2, 1]
Upvotes: 2