如何根据元素的索引组合两个数组?

时间:2017-02-01 22:39:19

标签: arrays ruby

我正在使用Ruby 2.4。我想根据它们的索引获取一个数组并将其元素添加到数组数组中。所以,如果我开始使用数组

[1, 2, 3]

我希望将它与数组

结合起来
[4, 5, 6]

我可以得到结果

[[1, 4], [2, 5], [3, 6]]

使用此功能

arr_of_arrays = arr_of_arrays.empty? ? arr : arr_of_arrays.zip(arr).map(&:flatten)

但是,如果我尝试添加元素多于原始元素,则会出现故障。所以,如果我尝试添加

[4, 5, 6, 7]

到原始数组,现在我正在

[[1, 4], [2, 5], [3, 6]]

但我想要的是

[[1, 4], [2, 5], [3, 6], [7]]

如何调整上述功能以实现此目的?

6 个答案:

答案 0 :(得分:1)

来自文档:

  

如果任何参数的大小小于初始数组的大小,则提供nil值。

所以你不必担心第二个数组更短的情况。

如果第一个数组较短,请用nil将其填充到第二个数组的长度。

之后您可以使用compact删除多余的nil

案例1:a更长

a = [1, 2, 3, 4, 5]
b = [6, 7, 8]

a[b.count-1] ||= nil
a.zip(b).map(&:flatten).map(&:compact)

结果:

[[1, 6], [2, 7], [3, 8], [4], [5]]

案例2:b更长

a = [1, 2, 3]
b = [4, 5, 6, 7, 8]

a[b.count-1] ||= nil
a.zip(b).map(&:flatten).map(&:compact)

结果:

[[1, 4], [2, 5], [3, 6], [7], [8]]   

包含nil的变体

a = [1, 2, 3, 4, 5]
b = [6, 7, 8]

a[b.count-1] ||= nil
b[a.count-1] ||= nil
a.zip(b).map(&:flatten)     # [[1, 6], [2, 7], [3, 8], [4, nil], [5, nil]]    

......和......

a = [1, 2, 3]
b = [4, 5, 6, 7, 8]

a[b.count-1] ||= nil
b[a.count-1] ||= nil
a.zip(b).map(&:flatten)     # [[1, 4], [2, 5], [3, 6], [nil, 7], [nil, 8]]

注释

  • 如果不得修改ab,请先在某处插入.clone以便克隆它们。
  • .flatten取自OP的例子;它会展平在示例中扮演整数角色的所有数组。根据需要保留或离开。

答案 1 :(得分:1)

看起来你想要一个“安全”的转置。它被称为安全,因为当子数组的长度不同时,通常的tranpose会引发错误:

def safe_transpose(*arrays)
  l = arrays.map(&:length).max
  arrays.map{|e| e.values_at(0...l)}.transpose.map(&:compact)
end

p safe_transpose([1, 2, 3, 4], [5, 6, 7])
#=> [[1, 5], [2, 6], [3, 7], [4]]

p safe_transpose([1, 2, 3], [4, 5, 6], [7, 8, 9])
#=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

如果你想保留填充的nils,你可以使用:

def safe_transpose(*arrays)
  l = arrays.map(&:length).max
  arrays.map{|e| e.values_at(0...l)}.transpose
end

p safe_transpose([1, 2, 3, 4], [5, 6, 7])
#=> [[1, 5], [2, 6], [3, 7], [4, nil]]

p safe_transpose([1, 2, 3], [4, 5, 6], [7, 8, 9])
#=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

原始数组未被修改。

答案 2 :(得分:0)

我愿意......

a << nil while a.length < b.length
a.zip(b).map(&:compact)

这会改变您的a数组,因此您可能希望对dup的{​​{1}}进行操作。

答案 3 :(得分:0)

a = [1,2,3]
b = [4, 5, 6, 7]
arr_of_arrays = []

我想你可以轻松检查b.size&gt; a.size是真的,所以

b.each_with_index{|elem, index| a[index].nil? ? arr_of_arrays << [elem] : arr_of_arrays << [a[index],elem]}

返回预期的数组数组:

=> [[1, 4], [2, 5], [3, 6], [7]]

答案 4 :(得分:0)

arr1 = [1, 2, 3]
arr2 = [4, 5, 6, 7]

def combine_two_arrays(arr1, arr2)
  new_arr = (arr1.size > arr2.size) ? arr1.zip(arr2) :  arr2.zip(arr1)
  new_arr.map { |arr| arr.compact.sort }
end 

combine_two_arrays(arr1, arr2)

答案 5 :(得分:0)

a = [1,2,3]
b = [4,5,6,7]

Array.new([a.size, b.size].max) { |i| [a[i],b[i]].compact }
  #=> [[1, 4], [2, 5], [3, 6], [7]] 

这假定ab的所有元素都不等于nil

如果您想要nil,请删除.compact

Array.new([a.size, b.size].max) { |i| [a[i],b[i]] }
  #=> [[1, 4], [2, 5], [3, 6], [nil, 7]]

在这种情况下,ab可以拥有nil个值。