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

Arrays 如何根据两个数组元素的索引组合它们?,arrays,ruby,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) 但是,如果我尝试添加一个元素,其中的元素比原始元素多,则会出现这种情

我正在使用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]]
如何调整上述功能以实现此目的?

我会

a << nil while a.length < b.length
a.zip(b).map(&:compact)
a来自文档:

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

因此,您不必担心第二个数组较短的情况

如果第一个数组较短,则用
nil
填充第二个数组的长度

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

案例1:
a
更长 结果:

[[1, 6], [2, 7], [3, 8], [4], [5]]
[[1, 4], [2, 5], [3, 6], [7], [8]]   
案例2:
b
更长 结果:

[[1, 6], [2, 7], [3, 8], [4], [5]]
[[1, 4], [2, 5], [3, 6], [7], [8]]   
包括
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]]
笔记
  • 如果不能修改
    a
    b
    ,请在某个位置插入
    .clone
    以预先克隆它们
  • .flatte
    取自OP的示例;它展平了在示例中扮演整数角色的所有数组。根据需要保持或停止
看起来你需要一个“安全”的转置。之所以称之为安全,是因为当子数组的长度不相同时,通常会引发错误:

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]]
如果要保留填充的零,可以使用:

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]]
原始数组不会被修改

a = [1,2,3]
b = [4, 5, 6, 7]
arr_of_arrays = []
我想你可以很容易地检查b.size>a.size是否正确,所以

b.each_with_index{|elem, index| a[index].nil? ? arr_of_arrays << [elem] : arr_of_arrays << [a[index],elem]}
这假设
a
b
的元素都不等于
nil

如果您希望包含
nil
s,只需删除
.compact

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

在这种情况下,允许
a
b
具有
nil
值。

如果我希望在其中一个数组较长的情况下出现一个“nil”元素,我该怎么做?例如,您的案例2将导致[[1,4]、[2,5]、[3,6]、[7,nil]、[8,nil]]。我意识到这是一个稍微不同的问题,所以如果你想让我做一个不同的帖子,我可以做塔特。谢谢<代码>a在情况2中发生变异。OP没有说明这是否是允许的(在这种情况下,我们应该假设这是不允许的),但即使这是可以的,
a
在案例1中也没有变异。这种不一致性是一个潜在的问题。2. <代码>映射(&:展平)
在示例中,如果数组的元素本身不是数组,则没有效果。然而,如果它们是数组,我们可能会有
a=[[1,2],3],4];b=[5,6];c=a.zip(b)#=>[[[[1,2,3],5],[4,6]],这是我们所期望的,但是
c.map(&:flatten)#=>[[1,2,3,5],[4,6]`,这不是规范的一部分。谢谢,@CarySwoveland在答案中添加了一个注释。
=> [[1, 4], [2, 5], [3, 6], [7]]
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)
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]] 
Array.new([a.size, b.size].max) { |i| [a[i],b[i]] }
  #=> [[1, 4], [2, 5], [3, 6], [nil, 7]]