如何交织在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 nils, 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