Во-первых, нам нужно прояснить, что означает «make the amount = 0». Последовательности LINQ неявно неизменяемы, поэтому невозможно изменить сумму на месте, но нам нужно вернуть новую последовательность (если вы действительно хотите изменить суммы на месте, я бы рекомендовал использовать массив и нормальный l oop). Ответ, предоставленный @Max, работает в принципе, но неэффективен, поскольку списки (и многие другие типы коллекций) имеют только медленный доступ к случайным элементам.
LINQ не имеет удобных инструментов для решения задачи из коробки . Используя только встроенные методы, решение может быть:
IEnumerable<int> accountNumbers = new List<int> { 0, 1, 2, 3, 4, 5, 5, 5, 6, 7, 3 };
IEnumerable<double> amounts = new List<double> { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 };
var possiblyInvalidAccountNumbers = accountNumbers.Skip(1); // The first account has no predecessor
var possiblyInvalidAmounts = amounts.Skip(1);
var validatedAmounts =
accountNumbers.Take(possiblyInvalidAccountNumbers.Count())
.Zip(possiblyInvalidAccountNumbers, (prevAccNo, accNo) => new { prevAccNo, accNo })
.Zip(possiblyInvalidAmounts, (numbers, amount) => numbers.prevAccNo != numbers.accNo ? amount : 0.0)
.Prepend(amounts.First());
Очевидно, этот код несколько запутан, поэтому возможный способ улучшить ясность может заключаться в написании ваших собственных методов расширения (например, Zip3()
может пригодиться метод, который принимает три входа).