Применить лямбда-функцию к диапазону элементов в C# - PullRequest
0 голосов
/ 04 августа 2020

Я понимаю, что лямбда-выражения можно использовать аналогично запросам LINQ для фильтрации коллекции или выбора ее элементов. Мне было интересно, можете ли вы также вызывать методы или применять что-то к элементам коллекции.

Например, если у меня есть класс с именем TrashCan, который может содержать список Trash элементов, например :

public class TrashCan
{
    ...
    public List<Trash> Trash { get; set; }

    public void AddTrash(Trash[] trashItems)
    {
        foreach (Trash trashItem in trashItems)
        {
            Trash.Add(trashItem);
        }
    }
}

Если у меня будет городской квартал, содержащий некоторое количество sh канистр, и я хочу сделать вид, что люди кладут в них какие-то sh банки, я бы хотел что-то сделать вот так:

var trashCans = new List<TrashCan>() { t1, t2, t3, t4, ..., tN };
var trashItems = new List<Trash>() { bananaPeel, beerBottle, flyer, ... };

var subTrashCans = trashCans.GetRange(3, 10);
var subTrashItems = trashItems.GetRange(5, 3);

// Normal way
foreach (var trashCan in subTrashCans)
{
    trashCan.AddTrash(subTrashItems.ToArray());
}

// Lambda way?
trashCans.GetRange(3, 10).DoForEach(x => AddTrash(trashItems.GetRange(5, 3))); // Can it be done somehow?

1 Ответ

1 голос
/ 04 августа 2020

Используйте List<T>.ForEach, если у вас есть List<T>

trashCans.ForEach(x => x.AddTrash(subTrashItems.GetRange(5, 3).ToArray()));

Но у этого есть один недостаток, мы вызываем .GetRange(3, 5).ToArray() один раз на каждой итерации, в то время как мы могли только назовите его один раз так:

// Either do it right at the declaration:
var subTrashItems = trashItems.GetRange(5, 3).ToArray();
trashCans.ForEach(x => x.AddTrash(subTrashItems));

// Or create a new variable and insert it again and again
var subTrashItemArray = subTrashItems.ToArray();
trashCans.ForEach(x => x.AddTrash(subTrashItemArray));

Короткая касательная к отложенному выполнению в LINQ:

LINQ поддерживает так называемое deferred execution, что означает, что ваше выражение LINQ будет выполнено только после того, как оно действительно необходимо. У этого есть много плюсов, но один недостаток: легко случайно выполнить один и тот же код несколько раз без необходимости. В вашем примере ваш вызов .ToArray() в вашем l oop, и он выполняет .GetRange(3, 5) один раз каждые l oop, что плохо. Вместо этого позвоните .ToArray() один раз при объявлении subTrashItems, и тогда он вам больше никогда не понадобится

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...