How can I transpose different sized ruby arrays?

前端 未结 3 1365
萌比男神i
萌比男神i 2020-12-17 22:38

I have an array:

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

I have the following code:

arr.transpose 

but it doesn\'t work,

相关标签:
3条回答
  • 2020-12-17 22:59

    If the length of the subarrays don’t match, an IndexError is raised.

    irb(main):002:0> arr=[[1,2,3],[4,5],[6]]
    => [[1, 2, 3], [4, 5], [6]]
    irb(main):003:0> arr.transpose
    IndexError: element size differs (2 should be 3)
        from (irb):3:in `transpose'
        from (irb):3
        from /Users/liuxingqi/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'
    

    should be:

    irb(main):004:0> arr=[[1,2,3],[4,5,6]]
    => [[1, 2, 3], [4, 5, 6]]
    irb(main):005:0> arr.transpose
    => [[1, 4], [2, 5], [3, 6]]
    

    or

    irb(main):006:0> arr=[[1,2],[3,4],[5,6]]
    => [[1, 2], [3, 4], [5, 6]]
    irb(main):007:0> arr.transpose
    => [[1, 3, 5], [2, 4, 6]]
    
    0 讨论(0)
  • 2020-12-17 23:01

    Using zip as in Stefan's answer is the most straightforward, but if you insist on using transpose, then:

    l = arr.map(&:length).max
    arr.map{|e| e.values_at(0...l)}.transpose
    # => [[1, 4, 6], [2, 5, nil], [3, nil, nil]]
    

    Or without using either:

    Array.new(arr.map(&:length).max){|i| arr.map{|e| e[i]}}
    # => [[1, 4, 6], [2, 5, nil], [3, nil, nil]]
    
    0 讨论(0)
  • 2020-12-17 23:11

    A similar answer was posted (but deleted) an hour earlier:

    arr = [[1, 2, 3], [4, 5], [6]]
    
    arr[0].zip(*arr[1..-1])
    #=> [[1, 4, 6], [2, 5, nil], [3, nil, nil]]
    

    The above is equivalent to:

    [1, 2, 3].zip([4, 5], [6])
    

    This approach assumes that your first sub-array is always the longest. Otherwise the result will be truncated:

    arr = [[1, 2], [3, 4, 5], [6]]
    
    arr[0].zip(*arr[1..-1])
    #=> [[1, 3, 6], [2, 4, nil]]  missing: [nil, 5, nil]
    
    0 讨论(0)
提交回复
热议问题