[英]How do I combine two arrays based on the index of their elements?
I'm using Ruby 2.4. 我正在使用Ruby 2.4。 I want to take an array and add its elements to an array of arrays, based on their index.
我想要一个数组,并根据其索引将其元素添加到数组的数组中。 So if I'm starting with an array
所以如果我从数组开始
[1, 2, 3]
and I want to combine that with the array 我想将其与数组结合
[4, 5, 6]
I can get the outcome 我可以得到结果
[[1, 4], [2, 5], [3, 6]]
using this function 使用此功能
arr_of_arrays = arr_of_arrays.empty? ? arr : arr_of_arrays.zip(arr).map(&:flatten)
However, this breaks down if I try and add an element with more elements than the original. 但是,如果我尝试添加的元素比原始元素多的话,这种情况就无法解决。 So if I try and add
所以,如果我尝试添加
[4, 5, 6, 7]
to the original array, right now I'm getting 到原始阵列,现在我得到
[[1, 4], [2, 5], [3, 6]]
but what I want is 但是我想要的是
[[1, 4], [2, 5], [3, 6], [7]]
How do I adjust my above function to achive this? 如何调整上述功能以实现此目的?
From the docs: 从文档:
If the size of any argument is less than the size of the initial array, nil values are supplied.
如果任何参数的大小小于初始数组的大小,则将提供nil值。
So you do not need to worry about the case where the second array is shorter. 因此,您不必担心第二个数组较短的情况。
If the first array is shorter, pad it out with nil
to the length of the second array. 如果第一个数组较短,则以
nil
填充到第二个数组的长度。
You can use compact
to remove the superfluous nil
s afterwards. 之后,您可以使用
compact
删除多余的nil
。
a
is longer a
更长 a = [1, 2, 3, 4, 5]
b = [6, 7, 8]
a[b.count-1] ||= nil
a.zip(b).map(&:flatten).map(&:compact)
Result: 结果:
[[1, 6], [2, 7], [3, 8], [4], [5]]
b
is longer b
更长 a = [1, 2, 3]
b = [4, 5, 6, 7, 8]
a[b.count-1] ||= nil
a.zip(b).map(&:flatten).map(&:compact)
Result: 结果:
[[1, 4], [2, 5], [3, 6], [7], [8]]
nil
included 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]]
... and ... ...和...
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
or b
must not be modified, insert a .clone
somewhere to clone them beforehand. a
或b
,请在某处插入.clone
以便对其进行克隆。 .flatten
was taken from the OP's example; .flatten
摘自OP的示例; it flattens any arrays that take the role of the integers in the example. It looks like you want a "safe" transpose. 看起来您想要一个“安全”的转置。 It's called safe because the usual
tranpose
raises an error when sub-arrays don't have the same length : 之所以称为安全,是因为当子数组的长度不同时,通常的
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]]
If you want to keep the padded nils, you can use : 如果要保留填充的指甲,可以使用:
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]]
The original arrays aren't modified. 原始数组未修改。
I would do... 我会做...
a << nil while a.length < b.length
a.zip(b).map(&:compact)
This will change your a
array, though, so you may want to do the operation on a dup
of a. 但是,这将更改您
a
数组,因此您可能需要对a的dup
进行操作。
a = [1,2,3]
b = [4, 5, 6, 7]
arr_of_arrays = []
i suppose you can easily check that b.size > a.size is true, so 我想您可以轻松地检查b.size> a.size是否为真,所以
b.each_with_index{|elem, index| a[index].nil? ? arr_of_arrays << [elem] : arr_of_arrays << [a[index],elem]}
returns the expected array of arrays : 返回期望的数组数组:
=> [[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]]
This assumes none of the elements of a
or b
equal nil
. 这假定
a
或b
的元素都不等于nil
。
If you want nil
s included, just remove .compact
: 如果要包含
nil
,只需删除.compact
:
Array.new([a.size, b.size].max) { |i| [a[i],b[i]] }
#=> [[1, 4], [2, 5], [3, 6], [nil, 7]]
In this case a
and b
are permitted to have nil
values. 在这种情况下,允许
a
和b
具有nil
值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.