Как сделать разумную "разницу в настройках" в Ruby?

Демо (я ожидаю результат [3]):

[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!

и

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

Как выполнить реальную разницу в настройках независимо от порядка входов?

Ps. В стороне, мне нужно сделать это для двух массивов с 2000 элементами. Обычно массив # 1 будет содержать меньше элементов, чем массив # 2, но это не гарантируется.

Ответы

Ответ 1

Оператор -, примененный к двум массивам a и b, дает относительное дополнение of b в a (элементы, находящиеся в a, но не в b).

То, что вы ищете, является симметричной разницей двух наборов (объединение обоих относительных дополнений между ними). Это сделает трюк:

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

Если вы работаете с объектами Set, вы можете использовать перегруженный ^ оператор.

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

Для дополнительного удовольствия вы также можете найти относительное дополнение intersection в union двух наборов:

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