Tutaj mam prosty przykład, aby znaleźć element na liście ciągów. Zwykle używam pętli lub anonimowego delegata, aby to zrobić w następujący sposób:
int GetItemIndex(string search)
{
int found = -1;
if ( _list != null )
{
foreach (string item in _list) // _list is an instance of List<string>
{
found++;
if ( string.Equals(search, item) )
{
break;
}
}
/* use anonymous delegate
string foundItem = _list.Find( delegate(string item) {
found++;
return string.Equals(search, item);
});
*/
}
return found;
}
LINQ jest dla mnie nowy. Jestem ciekawy, czy mogę użyć LINQ, aby znaleźć pozycję na liście? Jak to możliwe?
Odpowiedzi:
Jest kilka sposobów (pamiętaj, że to nie jest pełna lista).
1) Single zwróci pojedynczy wynik, ale zgłosi wyjątek, jeśli nie znajdzie żadnego lub więcej niż jednego (który może, ale nie musi być taki, jaki chcesz):
Uwaga
SingleOrDefault()
będzie zachowywać się tak samo, z tym wyjątkiem, że zwróci null dla typów referencyjnych lub wartość domyślną dla typów wartości, zamiast zgłaszać wyjątek.2) Gdzie zwróci wszystkie elementy, które spełniają twoje kryteria, więc możesz otrzymać IEnumerable z jednym elementem:
3) Najpierw zwróci pierwszy element, który spełnia Twoje kryteria:
Uwaga
FirstOrDefault()
będzie zachowywać się tak samo, z tym wyjątkiem, że zwróci null dla typów referencyjnych lub wartość domyślną dla typów wartości, zamiast zgłaszać wyjątek.źródło
ReadOnlyCollection
lubObservableCollection
?IEnumerable<T>
lubIQueryable<T>
Jeśli chcesz indeks elementu, zrobi to:
Nie możesz pozbyć się lambda w pierwszym przejściu.
Pamiętaj, że wyrzuci to, jeśli przedmiot nie istnieje. Rozwiązuje to problem, odwołując się do zerowych wartości ints:
Jeśli chcesz przedmiot:
Jeśli chcesz policzyć liczbę pasujących elementów:
Jeśli chcesz wszystkie pasujące elementy:
I nie zapomnij sprawdzić listy
null
w żadnym z tych przypadków.Lub użyj
(list ?? Enumerable.Empty<string>())
zamiastlist
.Dziękujemy Pavelowi za pomoc w komentarzach.
źródło
string.Equals
- nie ma w tym nic złego==
. Po drugie, wspomnę równieżFirstOrDefault
(w przypadkach, w których pozycja może nie istnieć) orazSelect
z indeksem, aby objąć przypadek, w którym potrzebny jest indeks pozycji (tak jak w próbce w samym pytaniu).ArgumentNullException
jeśli źródło jest zeroweJeśli to naprawdę
List<string>
nie potrzebujesz LINQ, po prostu użyj:Jeśli szukasz samego przedmiotu, spróbuj:
źródło
_list.Find(search)
drugiego.Czy chcesz element na liście lub sam przedmiot (zakładałby sam element).
Oto kilka opcji dla Ciebie:
źródło
Ta metoda jest łatwiejsza i bezpieczniejsza
bool insertOrderNew = lOrders.Find(r => r == "1234") == null ? true : false
źródło
true : false
poniżej, powinien działać tak samobool insertOrderNew = lOrders.Find(r => r == "1234") == null;
Jak o
IndexOf
?Na przykład
Zauważ, że zwraca -1, jeśli wartość nie występuje na liście
źródło
Kiedyś korzystałem ze Słownika, który jest pewnego rodzaju zindeksowaną listą, która da mi dokładnie to, czego chcę, kiedy chcę.
Ilekroć chcę na przykład uzyskać dostęp do moich wartości marginesów, zwracam się do mojego słownika:
W zależności od tego, co robisz, słownik może być przydatny.
źródło
Oto jeden ze sposobów przepisania metody korzystania z LINQ:
Tak więc nazywając to
GetItemIndex("two")
powróci1
,i
GetItemIndex("notthere")
wróci-1
.Odniesienie: linqsamples.com
źródło
Wypróbuj ten kod:
źródło
Jeśli musimy znaleźć element z listy, możemy użyć metody
Find
iFindAll
extensions, ale istnieje między nimi niewielka różnica. Oto przykład.źródło
Pomoże to w uzyskaniu pierwszej lub domyślnej wartości w wyszukiwaniu listy Linq
To wyszukiwanie znajdzie pierwszą lub domyślną wartość, którą zwróci.
źródło
Chcesz wyszukać obiekt na liście obiektów.
Pomoże to w uzyskaniu pierwszej lub domyślnej wartości w wyszukiwaniu listy Linq.
lub
źródło
Możesz użyć FirstOfDefault z rozszerzeniem Where Linq, aby uzyskać klasę MessageAction z IEnumerable. Reme
var action = Message.Actions.Where (e => e.targetByName == nazwa_klasy) .FirstOrDefault ();
gdzie
Lista działań {get; zestaw; }
źródło