繁体   English   中英

按索引映射两个数组

[英]Map two arrays by index

我有以下数组:

arr1 = [1, 2, 3, 4]
arr2 = [a, b, a, c]

我想要以下输出:

out = {'a' => [1, 3], 'b'=> [2], 'c' => [4]}

在 Ruby 中是否有一种简便的方法可以做到这一点? 目前,我正在使用循环和索引来创建哈希。

您可以编写以下内容。

arr1 = [1, 2, 3, 4]
arr2 = ['a', 'b', 'a', 'c']
arr1.zip(arr2).each_with_object(Hash.new { |h,k| h[k] = [] }) do |(n,c),h|
  h[c] << n
end
  #=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}

让我从一个简单的过程方法开始解释这个表达式,然后通过几个步骤来改进代码。


首先创建一个空散列,它将成为您想要的返回值:

h = {}

然后我们可以写如下

(0..arr1.size - 1).each do |i|
  n = arr1[i]
  c = arr2[i]
  h[c] = [] unless h.key?(c)
  h[c] << n
end
h #=>{"a"=>[1, 3], "b"=>[2], "c"=>[4]}

它更像 Ruby,但是迭代来自arr1arr2相应值对,即[1, 'a'][2, 'b']等等。 为此,我们使用方法Array#zip

pairs = arr1.zip(arr2)
  #=> [[1, "a"], [2, "b"], [3, "a"], [4, "c"]]

然后

h = {}
pairs.each do |pair| 
  n = pair.first
  c = pair.last
  h[c] = [] unless h.key?(c)
  h[c] << n
end
h #=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}

我们可以做的一个小改进是将数组分解应用于pair

h = {}
pairs.each do |n,c| 
  h[c] = [] unless h.key?(c)
  h[c] << n
end
h #=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}

下一个改进是将each替换为Enumerable#each_with_object以避免在开头使用h = {}并在结尾使用h

pairs.each_with_object({}) do |(n,c),h| 
  h[c] = [] unless h.key?(c)
  h[c] << n
end
  #=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}

请注意我是如何编写块变量的,其中h保存返回的对象(初始为空的散列)。 这是数组分解的另一个用途。 欲了解更多关于这个问题,看到这个文章。


前面的表达式很好,读起来很好,但经常看到以下调整:

pairs.each_with_object({}) do |(n,c),h| 
  (h[c] ||= []) << n
end
  #=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}

如果h没有键ch[c]返回nil ,所以h[c] ||= [] ,或h[c] = h[c] || [] h[c] = h[c] || [] ,变成h[c] = nil || [] h[c] = nil || [] ,因此h[c] = [] ,之后h[c] << n被执行。


没有比前面的表达式更好或更差,您可能还会看到我在开头提供的代码:

arr1.zip(arr2).each_with_object(Hash.new { |h,k| h[k] = [] }) do |(n,c),h|
  h[c] << n
end

这里块变量h被初始化为一个定义的空哈希

h = Hash.new { |h,k| h[k] = [] }

这采用了Hash::new的形式,它接受一个块而没有参数。 当以这种方式定义散列h ,如果h没有键c ,则执行h[c]会导致在执行h[c] << n之前执行h[c] = []

假设你的意思是

arr1 = [1, 2, 3, 4]
arr2 = %w[a b a c] # ["a", "b", "a", "d"]

所以你的第二个数组是一个字符串数组而不是变量


您可以使用group_byeach_with_index枚举器指向您的变量索引并使用第二个数组对其进行分组

arr1.group_by.each_with_index { |_, index| arr2[index] }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM