如何交织在Ruby中不同长度的数组
如果欲交织的一组中的Ruby阵列,并且每个阵列是相同的长度,我们可以这样做,以便:
If I want to interleave a set of arrays in Ruby, and each array was the same length, we could do so as:
a.zip(b).zip(c).flatten
然而,我们如何解决这个问题,如果数组可以是不同的尺寸?
However, how do we solve this problem if the arrays can be different sizes?
我们可以这样做:
def interleave(*args)
raise 'No arrays to interleave' if args.empty?
max_length = args.inject(0) { |length, elem| length = [length, elem.length].max }
output = Array.new
for i in 0...max_length
args.each { |elem|
output << elem[i] if i < elem.length
}
end
return output
end
但有一个更好的'红宝石'的方式,可能使用zip或调换或一些这样?
But is there a better 'Ruby' way, perhaps using zip or transpose or some such?
如果源数组没有无
在其中,你只需要扩展的第一个数组与无
S,拉链会自动垫无
其他人。这也意味着你会使用紧凑
来清理多余出来的条目是希望比显式循环更有效
If the source arrays don't have nil
in them, you only need to extend the first array with nil
s, zip will automatically pad the others with nil
. This also means you get to use compact
to clean the extra entries out which is hopefully more efficient than explicit loops
def interleave(a,*args)
max_length = args.map(&:size).max
padding = [nil]*[max_length-a.size, 0].max
(a+padding).zip(*args).flatten.compact
end
下面是一个稍微复杂一点的版本,如果数组的做的工作原理的包含无
Here is a slightly more complicated version that works if the arrays do contain nil
def interleave(*args)
max_length = args.map(&:size).max
pad = Object.new()
args = args.map{|a| a.dup.fill(pad,(a.size...max_length))}
([pad]*max_length).zip(*args).flatten-[pad]
end