2015-03-25 115 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}