Arrays 按相同项对数组中的子数组进行分组

Arrays 按相同项对数组中的子数组进行分组,arrays,ruby,Arrays,Ruby,我有一个数组 arr = [["cat", "15"], ["dog", "17"], ["cat", "20"], ["cat", "356"], ["dog", "89"], ["bird", "65"], ["dog", "336"], ["bird", "545"]] 我想按相同的第一项对子阵列进行分组,我只需要得到如下内容: arr = [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65","54

我有一个数组

arr = [["cat", "15"], ["dog", "17"], ["cat", "20"], ["cat", "356"], ["dog", "89"], ["bird", "65"], ["dog", "336"], ["bird", "545"]]
我想按相同的第一项对子阵列进行分组,我只需要得到如下内容:

arr = [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65","545"]]

有人能帮你吗?

下次如果你能添加一些你尝试过的步骤来获得你想要的东西,那就太好了,这里有一个快速解决方案:

> arr.group_by(&:shift).map(&:flatten)
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]]
但是,这将使原始arr发生变异


@Md.FarhanMemon有一个没有变异的好解决方案,下次如果你能添加一些你尝试过的步骤来获得你想要的,那就太好了,这里有一个快速的解决方案:

> arr.group_by(&:shift).map(&:flatten)
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]]
但是,这将使原始arr发生变异


@Md.FarhanMemon具有良好的解决方案,无需变异

替代解决方案,不改变原始对象,不需要dup

arr.group_by(&:first).map{ |k, v| [k] + v.map { |e| e[1] } }
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]]


替代解决方案,不更改原始对象,不需要dup

arr.group_by(&:first).map{ |k, v| [k] + v.map { |e| e[1] } }
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]]


另一种方法是在哈希中添加所有值:

animals = arr.each_with_object(Hash.new{|h, k| h[k] = []}) do |(animal_name, value), obj|
  obj[animal_name] << value
end
#=> {"cat"=>["15", "20", "356"], "dog"=>["17", "89", "336"], "bird"=>["65", "545"]}

另一种方法是在哈希中添加所有值:

animals = arr.each_with_object(Hash.new{|h, k| h[k] = []}) do |(animal_name, value), obj|
  obj[animal_name] << value
end
#=> {"cat"=>["15", "20", "356"], "dog"=>["17", "89", "336"], "bird"=>["65", "545"]}

其他答案已经提供了完美的解决方案。我发布这篇文章是为了展示一个鲜为人知的应用程序?方法它用给定的第一个元素扫描数组中的子数组,就像数组是散列一样。这可用于填充结果数组:


其他答案已经提供了完美的解决方案。我发布这篇文章是为了展示一个鲜为人知的应用程序?方法它用给定的第一个元素扫描数组中的子数组,就像数组是散列一样。这可用于填充结果数组:



从group_bygroup子阵列开始,按相同的第一项分组→ 首先,你应该考虑转换为散列来给出每个动物的值,即{CAT=>15, 20, 356,狗=>(17, 89, 336),Boe= >(65, 545)}。一种方法是:arr.group_by&:first.transform_值{| v | v.map&:last}从group_bygroup子数组按相同的第一项开始→ 首先,你应该考虑转换为散列来给出每个动物的值,即{CAT=>15, 20, 356,狗=>(17, 89, 336),Boe= >(65, 545)}。一种方法是:arr.group_by&:first.transform_values{| v | v.map&:last}好的,值得补充一点,这会改变原始数组。是的,这里需要深度dup。这一个什么都不做,但不要实现它。让他做点什么:好吧,这是必要的方法,任何人都有功能性的方法吗?uniq首先假设没有重复的方法好的,值得补充一点,这是对原始数组的变异。是的,我们这里需要深度dup。这一个什么都不做,但不要实现它。让他做点什么:好吧,这是必要的方法,任何人都有功能性的方法吗?uniq首先假设没有重复的方法或者[k]+v.map&:last或v.map&:last.unshiftkI编辑了您的答案,因为我假设|是一个拼写错误,但可能是数组|?@Stefan它不是一个拼写错误:是的,映射第二部分可能有多个变体。。v、 map&:last看起来较短,但可能会无意中丢弃重复项:['cat'].['1','1','1']=>[cat,1]哦,是的,我应该在答案中提到这一点。无论如何,thanxor[k]+v.map&:last或v.map&:last.unshiftkI编辑了你的答案,因为我认为&[k]+v.map&:last.unshiftkI是一个打字错误,但可能是数组|?@Stefan这不是打字错误:是的,第二部分可以有多种变体。。v、 map&:last看起来更短,但可能会无意中丢弃重复项:['cat'].['1','1','1']=>[cat,1]哦,是的,我应该在回答中提到这一点……无论如何,thanxNeat。我认为这是最有效的解决方案。我认为这是最有效的解决办法。
arr.each_with_object([]) do |(name, value), result|
  group = result.assoc(name)
  group ? group << value : result << [name, value]
end
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]]
name, *values = result.assoc('cat')
name   #=> "cat"
values #=> ["15", "20", "356"]