2012-06-28 8 views
14

Demo (Spodziewam spowodować [3]):Jak zrobić rozsądny "set-difference" w Ruby?

[1,2] - [1,2,3] => [] # Hmm 
[1,2,3] - [1,2] => [3] # I see 

a = [1,2].to_set => #<Set: {1, 2}> 
b = [1,2,3].to_set => #<Set: {1, 2, 3}> 
a - b    => #<Set: {}> WTF! 

I:

[1,2,9] - [1,2,3] => [9] # Hmm. Would like [[9],[3]] 

Jak wykonać jedną różnicę prawdziwy zestaw niezależnie od kolejności wejść?

Ps. Na marginesie, muszę to zrobić dla dwóch 2000-elementowych tablic. Zwykle tablica # 1 będzie miała mniej elementów niż tablica # 2, ale nie jest to gwarantowane.

Odpowiedz

49

The - operator przyłożonego do dwóch tablic a i b daje relative complement o b w a (elementy, które są w a ale nie w b).

To, czego szukasz, to symmetric difference dwóch zestawów (połączenie obu względnych uzupełnień między nimi). Będzie to rade:

a = [1, 2, 9] 
b = [1, 2, 3] 
a - b | b - a   # => [3, 9] 

Jeśli pracujesz na Set obiektów, możesz użyć przeciążony ^ operator:

c = Set[1, 2, 9] 
d = Set[1, 2, 3] 
c^d     # => #<Set: {3, 9}> 

Dla dodatkowej zabawy, można również znaleźć względną dopełnienie intersection w union z dwóch zestawów:

(a | b) - (a & b) # => #<Set: {3, 9}> 
+1

+1, dobra odpowiedź. Dodałem Array #^do mojej [biblioteki rozszerzeń] (http://rubydoc.info/gems/shenanigans/1.0.4/Array#%5E-instance_method), nie zawsze jest konieczne przechodzenie przez zestawy. –