Следующее не соответствует требованию использовать inject
(он же reduce
), но это то, как я бы это сделал.
arr = ['abc', 'def', '1234', '234', 'abcd', 'x', 'mnop', '5', 'zZzZ']
odd, even = arr.each_with_object(Hash.new { |h,k| h[k]=[] }) do |s,h|
h[s.size] << s
end.
values.
partition { |a| a.first.size.odd? }
#=> [[["abc", "def", "234"], ["x", "5"]],
# [["1234", "abcd", "mnop", "zZzZ"]]]
{ "odd"=>odd, "even"=>even }
#=> {"odd"=>[["abc", "def", "234"], ["x", "5"]],
# "even"=>[["1234", "abcd", "mnop", "zZzZ"]]}
Шаги следующие.
h = arr.each_with_object(Hash.new {|h,k| h[k]=[]}) do |s,h|
h[s.size] << s
end
#=> {3=>["abc", "def", "234"], 4=>["1234", "abcd", "mnop", "zZzZ"],
# 1=>["x", "5"]}
a = h.values
#=> [["abc", "def", "234"], ["1234", "abcd", "mnop", "zZzZ"],
# ["x", "5"]]
odd, even = a.partition { |a| a.first.size.odd? }
#=> [[["abc", "def", "234"], ["x", "5"]],
# [["1234", "abcd", "mnop", "zZzZ"]]]
{ "odd"=>odd, "even"=>even }
#=> {"odd"=>[["abc", "def", "234"], ["x", "5"]],
# "even"=>[["1234", "abcd", "mnop", "zZzZ"]]}
Если кто-то настаивает на установке квадратного колышка в круглом трюме (используя inject/reduce
), я полагаю, это можно сделать следующим образом.
arr.reduce({ "odd"=>[], "even"=>[] }) do |g,s|
oe = s.size.odd? ? "odd" : "even"
i = g[oe].find_index { |a| a.any? && a.first.size == s.size }
case i.nil?
when true then g[oe] << [s]
else g[oe][i] << s
end
g
end
#=> {"odd"=>[["abc", "def", "234"], ["x", "5"]],
# "even"=>[["1234", "abcd", "mnop", "zZzZ"]]}