Apply function to all elements of collection through LINQ [duplicate]
To pytanie ma już odpowiedź tutaj:
-
odpowiednik LINQ foreach dla IEnumerable
20 odpowiedzi
Ostatnio zacząłem z LINQ i jego niesamowite. Zastanawiałem się, czy LINQ pozwoli mi zastosować funkcję-dowolną funkcję-do wszystkich elementów zbioru, bez użycia foreach. Coś jak python lambda funkcje.
Na przykład, jeśli mam listę int, Mogę dodać stałą do każdego elementu używając LINQ
Jeśli mam tabelę DB, mogę ustawić pole dla wszystkich rekordów używając LINQ.
Używam C #
8 answers
Powszechnym sposobem podejścia do tego jest dodanie własnej ForEach
metody ogólnej na IEnumerable<T>
. Oto ten, który mamy w MoreLINQ :
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
source.ThrowIfNull("source");
action.ThrowIfNull("action");
foreach (T element in source)
{
action(element);
}
}
(Gdzie ThrowIfNull
jest metodą rozszerzenia na dowolnym typie odniesienia, która robi oczywistą rzecz.)
Kiedy już to masz, możesz pisać takie rzeczy jak:
people.Where(person => person.Age < 21)
.ForEach(person => person.EjectFromBar());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-05 06:11:06
Idiomatycznym sposobem na zrobienie tego z LINQ jest przetworzenie kolekcji i zwrócenie nowej kolekcji zmapowanej w pożądany sposób. Na przykład, aby dodać stałą do każdego elementu, potrzebujesz czegoś w rodzaju
var newNumbers = oldNumbers.Select(i => i + 8);
Robienie tego w sposób funkcjonalny zamiast mutowania stanu istniejącej kolekcji często pomaga oddzielić różne operacje w sposób, który jest zarówno łatwiejszy do odczytania, jak i łatwiejszy do rozumowania przez kompilator.
Jeśli jesteś w sytuacji, w której w rzeczywistości chcesz zastosować akcję do każdego elementu kolekcji (działanie z efektami ubocznymi, które nie są powiązane z rzeczywistą zawartością kolekcji), do którego LINQ nie jest najlepiej odpowiedni, chociaż możesz go udawać za pomocą Select
(lub napisać własną metodę rozszerzenia IEnumerable
, Jak Wiele osób ma.) W takim przypadku najlepiej trzymać się pętli foreach
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-05 06:03:04
Możesz również rozważyć przejście równolegle, zwłaszcza jeśli nie zależy ci na sekwencji i bardziej na zrobieniu czegoś dla każdego elementu:
SomeIEnumerable<T>.AsParallel().ForAll( Action<T> / Delegate / Lambda )
Na przykład:
var numbers = new[] { 1, 2, 3, 4, 5 };
numbers.AsParallel().ForAll( Console.WriteLine );
HTH.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-30 07:38:52
Haha, człowieku, zadałem to pytanie kilka godzin temu (tak jakby)...spróbuj tego:
Przykład:
someIntList.ForEach(i=>i+5);
ForEach()
jest jedną z wbudowanych metod. NET
Spowoduje to modyfikację listy, w przeciwieństwie do zwracania nowej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-13 07:50:54
Albo możesz to rozwalić.
Items.All(p => { p.IsAwesome = true; return true; });
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-13 07:51:07
Dla zbiorów, które nie obsługują ForEach
można użyć metody statycznej ForEach
w klasie Parallel
:
var options = new ParallelOptions() { MaxDegreeOfParallelism = 1 };
Parallel.ForEach(_your_collection_, options, x => x._Your_Method_());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-13 15:12:16
Możesz spróbować czegoś takiego
var foo = (from fooItems in context.footable select fooItems.fooID + 1);
Zwraca listę id +1, możesz zrobić to samo używając funkcji do tego, co masz w klauzuli select.
Update: zgodnie z sugestią Jona Skeeta jest to lepsza wersja fragmentu kodu, który właśnie zamieściłem:
var foo = context.footable.Select(foo => foo.fooID + 1);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-05 06:18:16
I found some way to perform in on dictionary contain my custom class methods
foreach (var item in this.Values.Where(p => p.IsActive == false))
item.Refresh();
Gdzie' to ' pochodzi z: Dictionary
class MyCustomClass
{
public void Refresh(){}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 08:26:42