2012-06-28 5 views
14

Demo (espero resultar [3]):¿Cómo hacer una sana "diferencia de configuración" en 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! 

Y:

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

¿Cómo se puede realizar un conjunto diferencia real, independientemente del orden de las entradas?

Ps. Como un aparte, necesito hacer esto para dos arrays de 2000 elementos. Por lo general, la matriz n. ° 1 tendrá menos elementos que la matriz n. ° 2, pero esto no está garantizado.

Respuesta

49

El - operator aplicado a dos matrices a y b da relative complement de b en a (elementos que están en a pero no en b).

Lo que está buscando es el symmetric difference de dos juegos (la unión de ambos complementos relativos entre los dos). Esto va a hacer el truco:

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

Si está operando en Set objetos, se puede utilizar la sobrecarga ^ operator:

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

Para mayor diversión, usted podría también encontrar el complemento relativo de la intersection en el union de los dos conjuntos:

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

+1, buena respuesta. Agregué Array #^a mi [biblioteca de extensión] (http://rubydoc.info/gems/shenanigans/1.0.4/Array#%5E-instance_method), no siempre es necesario pasar por los conjuntos. –

Cuestiones relacionadas