2014-04-02 42 views
1

有沒有這樣做的一般方法?將二維陣列的子陣列一起編碼

每個子數組將具有相同的長度。

c = [[1,1,1,1], [2,2,2,2], [3,3,3,3]] 

c[0].zip(c[1], c[2]) 

=> [[1,2,3][1,2,3],[1,2,3],[1,2,3]] 

謝謝。

+2

'c'中的數組總是全部大小相同? – toro2k

+3

'c.transpose'就是你需要的所有 –

+1

即使你選擇了一個答案,請回答@ toro2k的問題,還有一個問題:你是否打算讓每一行c有相同的元素(例如[2,2, 2,2]?我問,因爲我剛剛發佈的答案是如果對這兩個問題的答案都是「是」,另一種做法是做你想做的事情。更一般地說,因爲其他人將來會閱讀你的問題,所以重要的是清除 –

回答

6

要與zip做到這一點:

c.first.zip(*c.drop(1)) 

否則,

c.transpose 

將是一個對稱的方式。

+2

對c.transpose爲+1。 –

+1

'#zip'很好,安全。##轉置'不安全,如果數組大小不同。#1爲'#zip'。 –

+0

太棒了。謝謝。 –

3

編輯:我發現爲什麼我的方法是如此之快,這可能是有好有壞,取決於結果怎麼樣都可以使用的影響。假設

c = [[1,1,1],[2,2,2]] 

然後

d = [c.map(&:first)]*c.first.size #=> [a, b, c] 

其中:

a = b = c = [1,2] 

但那是因爲:

a.object_id = b.object_id = c.object.id 

那麼 「壞」 的是,如果d的元素被改變,所有的元素該行中的ts更改爲相同的值。 「好」是,如果數組d不會被改變,這個方法不僅快,但它只需要很少的存儲來保存結果數組d的(表示)。

然而,事實是,如果d不會改變,創建它是沒有意義的。相反,代碼應該重構,以便在隨後的操作中只使用d的第一個元素。 (這句話適用於所有的方法,當然。)編輯

end如果你打算的c每個元素(行),以包含都彼此相等的元素,它們是大小相同,如你的榜樣,你可以這樣做:

[c.map(&:first)]*c.first.size 

出於好奇,我決定將基準這種方法,並提供兩個@sawa。

標杆代碼

require 'benchmark' 

def sawa_zip(c)  c.first.zip(*c.drop(1))  end 
def sawa_transpose(c) c.transpose     end 
def cary(c)   [c.map(&:first)]*c.first.size end 

def bench_em(n, m, iterations) 
    puts "n = #{n}, m = #{m}, interations = #{iterations}\n" 
    c = n.times.map { Array.new }.map.with_index { |_,i| Array.new(m,i) } 
    Benchmark.bm(%w[sawa_zip, sawa_transpose, cary].map(&:size).max) do |bm| 

    bm.report('sawa_zip') do 
     iterations.times do 
     sawa_zip(c) 
     end 
    end 

    bm.report('sawa_transpose') do 
    iterations.times do 
     sawa_transpose(c) 
    end 
    end 

    bm.report('cary') do 
     iterations.times do 
     cary(c) 
     end 
    end 
    end 
end 

bench_em(200, 300,5) 
bench_em(2000, 3000,5) 
bench_em(10000, 15000,1) 

基準測試結果

應該記住的是,這種比較是唯一有效的,當矩陣中的每一行中的所有元素都是平等的。我曾預料過我建議的方法相對較快,但速度不如結果所示。

n = 200, m = 300, interations = 5 
         user  system  total  real 
sawa_zip   0.010000 0.000000 0.010000 ( 0.007858) 
sawa_transpose 0.000000 0.000000 0.000000 ( 0.006568) 
cary    0.000000 0.000000 0.000000 ( 0.000113) 

n = 2000, m = 3000, interations = 5 
         user  system  total  real 
sawa_zip   1.010000 0.070000 1.080000 ( 1.080286) 
sawa_transpose 0.800000 0.060000 0.860000 ( 0.860823) 
cary    0.000000 0.000000 0.000000 ( 0.001669) 

n = 10000, m = 15000, interations = 1 
         user  system  total  real 
sawa_zip   25.760000 0.740000 26.500000 (26.668127) 
sawa_transpose 18.200000 0.630000 18.830000 (18.870150) 
cary    0.000000 0.000000 0.000000 ( 0.002412)