Можем ли мы решить проблему ниже, инициализируя ключ хеша значением по умолчанию? - PullRequest
0 голосов
/ 12 июля 2019

Напишите метод, который группирует вышеупомянутый хэш в 2 группы 'четной' и 'нечетной' длины, используя 'inject'. input - "['abc', 'def', '1234', '234', 'abcd', 'x', 'mnop', '5', 'zZzZ']"

Мой код, указанный ниже, уже работает. Но я хочу узнать лучший способ сделать это, используя значение по умолчанию для ключа хеша. Я хотел сказать что-то вроде ниже -

h=Hash.new { |hash, key| hash[key] = []}

Решение:

class Array
  def group_even_odd
    key_hash = group_by(&:length)
    key_array = %w(even odd)
    key_hash.each_with_object('odd' => [], 'even' => []) do |(key, value), even_odd_hash|
      even_odd_hash[key_array[key % 2]].push(value)
      even_odd_hash
    end
  end
end
if ARGV.empty?
  puts 'Please provide an input'
else
  input = ARGV[0].scan(/\w+/).map(&:to_s)
  puts input.group_even_odd
end

Ожидаемое и фактическое совпадают, код работает.

Ожидаемый результат -
{"odd" => [["abc", "def", "234"], ["x", "5"]], "even" => [["1234", "abcd", "mnop" , "zZzZ"]]}

Ответы [ 2 ]

1 голос
/ 12 июля 2019

Один возможный вариант, учитывая

ary = ["abc", "def", "1234", "234", "abcd", "x", "mnop", "5", "zZzZ"]

Первая группа по четному нечетному, затем группа по размеру:

ary.group_by { |e| e.size.even? ? 'even' : 'odd' }
   .transform_values { |v| v.group_by(&:size).values }

#= {"odd"=>[["abc", "def", "234"], ["x", "5"]], "even"=>[["1234", "abcd", "mnop", "zZzZ"]]}


Первый шаг, чтобы объяснить:
ary.group_by { |e| e.size.even? ? 'even' : 'odd' }
#=> {"odd"=>["abc", "def", "234", "x", "5"], "even"=>["1234", "abcd", "mnop", "zZzZ"]}

Затем Hash # transform_values ​​ группировка каждого по размеру.

0 голосов
/ 12 июля 2019

Следующее не соответствует требованию использовать 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"]]} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...