Ruby 填充新的\u散列,其中来自旧\u散列的唯一值是键,来自旧\u散列的键是值,分组到数组中。

Ruby 填充新的\u散列,其中来自旧\u散列的唯一值是键,来自旧\u散列的键是值,分组到数组中。,ruby,arrays,hash,enumerable,Ruby,Arrays,Hash,Enumerable,我是编程新手,从Ruby开始。 仅使用.each,我的挑战是: animals = { 'leopard' => 1, 'gorilla' => 3, 'hippo' => 4, 'zebra' => 1, 'lion' => 2, 'eagle' => 3, 'ostrich' => 2, 'alligator' => 6 } 在此哈希中,动物按计数分组: anima

我是编程新手,从Ruby开始。 仅使用.each,我的挑战是:

animals = {
  'leopard'   => 1,
  'gorilla'   => 3,
  'hippo'     => 4,
  'zebra'     => 1,
  'lion'      => 2,
  'eagle'     => 3,
  'ostrich'   => 2,
  'alligator' => 6
}
在此哈希中,动物按计数分组:

animals_by_count = {
   1 => ['leopard', 'zebra'],
   2 => ['lion', 'ostrich'],
   3 => ['gorilla', 'eagle'],
   4 => ['hippo'],
   6 => ['alligator']
}
这是我的代码,它不能正常工作。 同样,我必须只使用.each,而不使用.map.inject.select或任何其他方法

animals_by_count = {}
animals.each do |animal, count|
  animals_array = []
  if !animals_by_count.has_key?(count)
    animals_by_count[count] = animals_array << animal
  elsif animals_by_count.has_key?(count)
    animals_by_count[count] = animals_array << animal
  end

 end
animals_by_count={}
动物。每一只都做|动物,数一数|
动物_数组=[]
如果!动物按计数。有计数键吗?(计数)
动物\u按\u计数[计数]=动物\u数组您可以执行以下操作:-

animals = {
  'leopard'   => 1,
  'gorilla'   => 3,
  'hippo'     => 4,
  'zebra'     => 1,
  'lion'      => 2,
  'eagle'     => 3,
  'ostrich'   => 2,
  'alligator' => 6
}

animals_by_count = {}
animals.each do |animal, count|
  if animals_by_count.has_key?(count)
    animals_by_count[count].push(animal)
  else
    animals_by_count[count] = [animal]
  end
end

animals_by_count
# => {1=>["leopard", "zebra"],
#     3=>["gorilla", "eagle"],
#     4=>["hippo"],
#     2=>["lion", "ostrich"],
#     6=>["alligator"]}
为什么不做你的呢

您可以执行以下操作:-

animals = {
  'leopard'   => 1,
  'gorilla'   => 3,
  'hippo'     => 4,
  'zebra'     => 1,
  'lion'      => 2,
  'eagle'     => 3,
  'ostrich'   => 2,
  'alligator' => 6
}

animals_by_count = {}
animals.each do |animal, count|
  if animals_by_count.has_key?(count)
    animals_by_count[count].push(animal)
  else
    animals_by_count[count] = [animal]
  end
end

animals_by_count
# => {1=>["leopard", "zebra"],
#     3=>["gorilla", "eagle"],
#     4=>["hippo"],
#     2=>["lion", "ostrich"],
#     6=>["alligator"]}
为什么不做你的呢


@奥雅纳已经解释了为什么你的代码不起作用,并表明你必须修复它。我想向您展示一些有经验的Rubiest可能使用的变体和替代方案。这些可分为两类:

  • 构建一个新的散列,一次添加一个
    动物的元素
  • 使用
构建一个新的散列

这是您采取的方法,@Arup修复了该方法。让我稍微更改一下奥雅纳的代码:

h = {}
animals.each do |(name, num)|
  h[num] = [] unless h.key?(num)
  h[num] << name
end
h
  #=> {1=>["leopard", "zebra"],
  #    3=>["gorilla", "eagle"],
  #    4=>["hippo"],
  #    2=>["lion", "ostrich"], 6=>["alligator"]}

h[num] = h[num] || []
可与下一行组合:

h[num] = (h[num] || []) << name
如果此散列由与散列项不对应的键访问,则将
h
k
传递到块,以允许您为该键创建值。这里我们希望它是一个空数组。这使我们能够写:

animals.each_with_object(Hash.new { |h,k| h[k] = [] }) { |(name,num),h|
  h[num] << name }
请注意块参数的顺序:
|(name,num),h |
用于
每个带有_对象的
,h,(name,num)
用于
减少
。另外,使用
reduce
时,对象(此处
h
)必须返回到
reduce
。这就是孤独的
h
作为
reduce
块中的最后一条语句的原因

使用
Enmerable\goup\u by

第二种常见的解决此类问题的方法是使用
group\u by
,它返回以下哈希:

h = animals.group_by { |_,v| v }
  #=> {1=>[["leopard", 1], ["zebra", 1]],
  #    3=>[["gorilla", 3], ["eagle", 3]],
  #    4=>[["hippo", 4]],
  #    2=>[["lion", 2], ["ostrich", 2]],
  #    6=>[["alligator", 6]]}
现在我们需要做的就是操作散列值(例如,将
[[“leopard”,1],“zebra”,1]]
更改为
[“leopard”,“zebra”]

有两种方法可以做到这一点。一种是枚举哈希键并修改值:

h.keys.each { |k| h[k] = h[k].map(&:first) }
h
另一个是构建新的哈希:

g = {}
h.each { |k,v| g[k] = v.map(&:first) }
g
也可以写成:

h.each_with_object({}) { |(k,v),g| g[k] = v.map(&:first) }

@奥雅纳已经解释了为什么你的代码不起作用,并说明了你必须修复它。我想向你展示一些有经验的Rubiest可能会使用的变体和替代方案。这些分为两类:

  • 构建一个新的散列,一次添加一个
    动物的元素
  • 使用
构建一个新的散列

这是您采取的方法,@Arup修复了此问题。让我稍微更改一下Arup的代码:

h = {}
animals.each do |(name, num)|
  h[num] = [] unless h.key?(num)
  h[num] << name
end
h
  #=> {1=>["leopard", "zebra"],
  #    3=>["gorilla", "eagle"],
  #    4=>["hippo"],
  #    2=>["lion", "ostrich"], 6=>["alligator"]}

h[num] = h[num] || []
可与下一行组合:

h[num] = (h[num] || []) << name
如果此散列由与散列项不对应的键访问,则将
h
k
传递到块,以允许您为该键创建值。这里我们希望该值为空数组。这允许我们写入:

animals.each_with_object(Hash.new { |h,k| h[k] = [] }) { |(name,num),h|
  h[num] << name }
请注意块参数的顺序:
|(name,num),h |
用于
每个带有_object的
,h,(name,num)|
用于
reduce
。另外,当使用
reduce
时,对象(此处
h
)必须返回到
reduce
。这就是将
h
作为
reduce
块中最后一条语句的原因

使用
Enmerable\goup\u by

第二种常见的解决此类问题的方法是使用
group\u by
,它返回以下哈希:

h = animals.group_by { |_,v| v }
  #=> {1=>[["leopard", 1], ["zebra", 1]],
  #    3=>[["gorilla", 3], ["eagle", 3]],
  #    4=>[["hippo", 4]],
  #    2=>[["lion", 2], ["ostrich", 2]],
  #    6=>[["alligator", 6]]}
现在我们需要做的就是操作散列值(例如,将
[[“leopard”,1],“zebra”,1]]
更改为
[“leopard”,“zebra”]

有两种方法可以做到这一点。一种是枚举哈希键并修改值:

h.keys.each { |k| h[k] = h[k].map(&:first) }
h
另一个是构建新的哈希:

g = {}
h.each { |k,v| g[k] = v.map(&:first) }
g
也可以写成:

h.each_with_object({}) { |(k,v),g| g[k] = v.map(&:first) }

动物。每个{名称,num |(h[num]|=[])
动物。每个{名称,num |(h[num]|=[]))+1给出这样一个详细的解释。OP应该接受这一点作为答案。+1给出这样一个详细的解释。OP应该接受这一点作为答案。请不要只发布一行代码作为答案,而没有任何解释或上下文。你真的应该有时间解释OP的尝试失败的原因以及这段代码工作的原因。请不要只发布一行code是一个没有任何解释或上下文的答案。你真的应该花时间来解释OP的尝试失败的原因以及这段代码工作的原因。