2015-03-25 110 views
0

我有兩個二維陣列,比較二維陣列

a = [[17360, "Z51.89"], 
[17361, "S93.601A"], 
[17362, "H66.91"], 
[17363, "H25.12"], 
[17364, "Z01.01"], 
[17365, "Z00.121"], 
[17366, "Z00.129"], 
[17367, "K57.90"], 
[17368, "I63.9"]] 

b = [[17360, "I87.2"], 
[17361, "s93.601"], 
[17362, "h66.91"], 
[17363, "h25.12"], 
[17364, "Z51.89"], 
[17365, "z00.121"], 
[17366, "z00.129"], 
[17367, "k55.9"], 
[17368, "I63.9"]] 

我想在兩個陣列來計算類似的行,而不管字符案件,即"h25.12"將等於"H25.12"

我試過,

count = a.count - (a - b).count 

(a - b)收益

[[17360, "Z51.89"], 
[17361, "S93.601A"], 
[17362, "H66.91"], 
[17363, "H25.12"], 
[17364, "Z01.01"], 
[17365, "Z00.121"], 
[17366, "Z00.129"], 
[17367, "K57.90"]] 

我需要算作5因爲有5個類似的行,當我們不考慮字符大小寫。

+0

爲什麼選擇近距離投票? – 2015-03-25 06:39:08

+4

這些不是二維數組,Ruby沒有這種東西(除非你想要計算Matrix),那些數組就是數組。 – 2015-03-25 06:47:33

+0

好的!這意味着按照慣例,Ruby沒有「二維數組」? – 2015-03-25 07:03:13

回答

3

而不是a - b你應該這樣做:

a.map{|k,v| [k,v.downcase]} - b.map{|k,v| [k,v.downcase]} # case-insensitive 
1

它會轉換內部數組的第二個元素upcase兩個數組,那麼你可以執行減法,那麼它將返回確切的結果要

a.map{|first,second| [first,second.upcase]} - b.map{|first,second| [first,second.upcase]} 
+0

考慮解釋你的anwser! – 2015-03-25 12:10:31

+0

我已經解釋了謝謝! – user3118220 2015-03-25 12:42:02

0
a.count - (a.map{|e| [e[0],e[1].downcase] } - b.map{|e| [e[0],e[1].downcase] }).count 

上述地圖ab到新的陣列,其中所述第二子陣列元件是downcase。

2

您可以將陣列哈希,並使用Enumerable#count與塊。

b_hash = b.to_h 
a.to_h.count {|k, v| b_hash[k] && b_hash[k].downcase == v.downcase } 
# => 5 
0

要計數相似,所以&(AND)操作更合適。

(a.map { |k, v| [k, v.upcase] } & b.map { |k, v| [k, v.upcase] }).count 
0

使用Proc和 '&':

procedure = Proc.new { |i, j| [i, j.upcase] } 
(a.map(&procedure) & b.map(&procedure)).count 
#=> 5 

爲了更好的理解,讓我們把它簡化:

new_a = a.map {|i, j| [i, j.upcase]} 
new_b = b.map {|i, j| [i, j.upcase]} 

# Set intersection using '&' 
(new_a & new_b).count 
#=> 5 
0

我假設的a第i個元素是與被比較b的第i個元素。 (編輯:由OP隨後的評論證實了這一解釋。)

我會傾向於使用索引來避免較大的臨時數組的建設。以下是可能完成的兩種方法。

#1使用指數

[a.size,b.size].min.size.times.count do |i| 
    af,al=a[i] 
    bf,bl=b[i]; 
    af==bf && al.downcase==bl.downcase 
end 
    #=> 5 

#2 Refinements

我在給這個解決方案的目的是爲了說明使用Refinements。我不會主張用它來解決手頭的問題,但這個問題爲展示這項技術如何應用​​提供了一個很好的途徑。

我無法弄清楚如何最好地做到這一點,所以我在SO上發佈了這個question。我已經在下面應用@ ZackAnderson的答案。

module M 
    refine String do 
    alias :dbl_eql :== 
    def ==(other) 
     downcase.dbl_eql(other.downcase) 
    end 
    end 

    refine Array do 
    def ==(other) 
     zip(other).all? {|x, y| x == y} 
    end 
    end 
end 

'a' == 'A'   #=> false (as expected) 
[1,'a'] == [1,'A'] #=> false (as expected) 

using M 
'a' == 'A'   #=> true 
[1,'a'] == [1,'A'] #=> true 

我可以使用Enumerable#zip,但對於各種我會結合使用Object#to_enumKernel#loopEnumerator#next

ea, eb = a.to_enum, b.to_enum 
cnt = 0 
loop do 
    cnt += 1 if ea.next == eb.next 
end 
cnt #=> 5  
1

你可以壓縮它們,然後用數塊形式:

a.zip(b).count{|e| e[0][1].downcase == e[1][1].downcase}