2010-12-20 17 views
10

Właśnie spędziłem ponad godzinę debugowania błąd w naszym kodzie, który w końcu okazał się być coś o sposobie Enumerable.Except których nie wiemy o:dlaczego Enumerable.Except zwraca DISTINCT items?

var ilist = new[] { 1, 1, 1, 1 }; 
var ilist2 = Enumerable.Empty<int>(); 
ilist.Except(ilist2); // returns { 1 } as opposed to { 1, 1, 1, 1 } 

lub bardziej ogólnie:

var ilist3 = new[] { 1 }; 
var ilist4 = new[] { 1, 1, 2, 2, 3 }; 
ilist4.Except(ilist3); // returns { 2, 3 } as opposed to { 2, 2, 3 } 

Patrząc na stronie MSDN:

Ta metoda zwraca te elementy najpierw, że nie pojawiają się w sekundę. To nie zwraca również tych elementów w sekundach, które nie pojawiają się w pierwszej.

Rozumiem, że w takich przypadkach:

var ilist = new[] { 1, 1, 1, 1 }; 
var ilist2 = new[] { 1 }; 
ilist.Except(ilist2); // returns an empty array 

masz pustą tablicę, ponieważ każdy element w pierwszej tablicy „pojawi się” w drugim i dlatego powinny zostać usunięte.

Ale dlaczego otrzymujemy odrębne wystąpienia wszystkich innych elementów, które nie pojawiają się w drugiej tablicy? Jakie jest uzasadnienie tego zachowania?

+0

Moim zdaniem, zapachy jak błąd lub niezamierzona funkcjonalność. Strona MSDN nie mówi o wyraźnym wyniku ... –

+7

To nie jest błąd. Metoda 'Except' ma być przetłumaczona na operator SQL' EXCEPT', który jest zdefiniowany jako operacja set. Będąc operacją zestawu, zwracane są tylko odrębne elementy. "Odrębność" wynika z używania przez MSDN terminologii "zestaw". – Gabe

Odpowiedz

16

Z pewnością nie mogę powiedzieć na pewno, dlaczego zdecydowali się to zrobić w ten sposób. Jednak dam mu szansę.

MSDN opisuje wyjątkiem tego:

Powoduje zestaw różnicę dwóch sekwencji za pomocą domyślnej równości porównywarka porównać wartości.

Set jest opisane jak to:

Zestaw jest zbiorem odrębne obiektów, uważany jako obiekt w sobie

+1

+1, to brzmi rozsądnie. – driis

+2

+1 Implementacja wykorzystuje skróty mieszające do zredukowania problemu z O (NxN) do O (N). – dthorpe