将数组中的数组压缩成另一个数组

6
假设我有一个数组:
arr1 = ["a", "b", "c"]

我想将一个数组的数组压缩成一个数组

arr2 = [[1, "foo"], [2, "bar"], [3, "baz"]]

所以最终结果是

[["a", 1, "foo"], ["b", 2, "bar"], ["c", 3, "baz"]]

我现在正在做的是 arr1.zip(arr2).map!(&:flatten),但我想知道是否有更好的方法?


脑海中首先想到的是使用 each_index 迭代,然后将 arr1 的元素注入到 arr2 的相应元素中。如果你觉得这有用,我可以发布出来,但似乎比你现在拥有的更长。 - onebree
我不认为你的方法有什么问题,但另一种选择可能是 arr2.each_with_index{|a,i| a.unshift(arr1[i])} ... 但实际上,你的方法更好。 - SteveTurczyn
4个回答

13

另一种方法是:

arr1.zip(*arr2.transpose)
# => [["a", 1, "foo"], ["b", 2, "bar"], ["c", 3, "baz"]]

那是转置的巧妙应用。 - aaron-coding
1
如果arr2包含不同大小的数组,则此方法将无法工作,也不对称。如果两个数组都包含数组,则此方法也无法工作。OP的解决方案仍然更清晰,但我必须承认这非常聪明。 - ndnenkov

3

以下是另外两种(相关性很高的)方法:

enum = arr1.to_enum
arr2.map { |a| [enum.next].concat(a) }
  #=> [["a", 1, "foo"], ["b", 2, "bar"], ["c", 3, "baz"]] 

或者

arr1_cpy = arr1.dup
arr2.map { |a| [arr1_cpy.shift].concat(a) }
  #=> [["a", 1, "foo"], ["b", 2, "bar"], ["c", 3, "baz"]] 

1
arr2.each_with_index{ |el,i| el.unshift(arr1[i]) }

也许你更喜欢这个?

1
如果你正在执行unshift操作,那么你正在改变对象,因此你实际上不需要map!。原始数组将无论如何发生更改。 - SteveTurczyn
@SteveTurczyn 说得好,已经更新了。虽然Doguita的回答更好。 - aaron-coding

1
如果你需要arr2的内容在arr1之前,你不能使用#transpose技巧。但是,你可以:
arr1.map.with_index { |el, i| [*arr2[i], el] }
# => [[1, "foo", "a"], [2, "bar", "b"], [3, "baz", "c"]]

这种方法的优点包括:

  1. 不会改变原始数组
  2. 让您可以选择顺序

就性能而言,Doguita的回答似乎更好:
arr1 = %w(foo) * 10_000
arr2 = arr1.length.times.map { |i| [i, i.to_s(2)] }
Benchmark.bmbm(20) do |x|
  x.report("zip & transpose:") { arr1.zip(*arr2.transpose) }
  x.report("map & with_index:") { arr1.map.with_index { |v, i| [v, *arr2[i]] } }
end

Rehearsal --------------------------------------------------------
zip & transpose:       0.000902   0.000233   0.001135 (  0.001107)
map & with_index:      0.004206   0.002308   0.006514 (  0.006828)
----------------------------------------------- total: 0.007649sec

                           user     system      total        real
zip & transpose:       0.001474   0.000045   0.001519 (  0.001471)
map & with_index:      0.002155   0.000059   0.002214 (  0.002282)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接