Список <T> .ForEach с индексом

m пытается найти эквивалент LINQ следующего кода:

NameValueCollection nvc = new NameValueCollection();

List donations = new List();
donations.Add(new BusinessLogic.Donation(0, "", "", "");
donations.Add(new BusinessLogic.Donation(0, "", "", "");
donations.Add(new BusinessLogic.Donation(0, "", "", "");

for(var i = 0; i < donations.Count(); i++)
{
    // NOTE: item_number_ + i - I need to be able to do this
    nvc.Add("item_number_" + i, donations[i].AccountName);
}

Я надеялся, что смогу использовать что-то вроде:

NameValueCollection nvc = new NameValueCollection();

List donations = new List();
donations.Add(new BusinessLogic.Donation(0, "", "", "");
donations.Add(new BusinessLogic.Donation(0, "", "", "");
donations.Add(new BusinessLogic.Donation(0, "", "", "");

donations.ForEach(x => nvc.Add("item_name_" + ??, x.AccountName);

Но я'Мы не нашли способ определить, на какой итерации находится цикл. Любая помощь будет оценена!

 lc.24 окт. 2012 г., 19:18
Вы могли бы сделатьint i = 0; donations.ForEach(x=> nvc.Add("item_name_" + i++, ... но не уверен, насколько это безопасно.
 Josh C.24 окт. 2012 г., 19:17
Есть ли у пожертвования метод .IndexOf ()?

Ответы на вопрос(8)

Решение Вопроса

LINQ не делаетне иметьForEach метод, и не зря. LINQ для выполнениязапросы, Он предназначен для получения информации из какого-либо источника данных. этоне предназначен для изменения источников данных. LINQ запросы не должныне вызывает побочных эффектов, это именно то, что выздесь делаешь

List учебный классделает иметьForEach метод, который вы используете. Потому что это'на самом деле не вSystem.Linq пространство имен это 'технически не является частью LINQ.

В этом нет ничего плохогоfor Цикл в вашем вопросе. Было бы неправильно (с точки зрения хорошей практики) пытаться изменить его так, как выпытаюсь.

Вот это ссылка, которая обсуждает этот вопрос более подробно.

Теперь, если вы хотите игнорировать этот совет и использоватьForEach метод в любом случае, этоНетрудно написать тот, который обеспечивает индекс для действия:

public static void ForEach(this IEnumerable sequence, Action action)
{
    // argument null checking omitted
    int i = 0;
    foreach (T item in sequence)
    {
        action(i, item);
        i++;
    }
}
 Servy24 окт. 2012 г., 19:24
@JamesHill It 'это методList, Это'не метод вSystem.Linq
 James Hill24 окт. 2012 г., 19:30
@ Служу, я так думаюОчевидно, что мне нужно ненадолго отойти от компьютера. Я думаю, что кофе в порядке. Спасибо, что поправил меня.
 James Hill24 окт. 2012 г., 19:23
Ну яМы, очевидно, использовали неверную терминологию. Моя коллекцияDonation действительно есть.ForEach() метод.
 JDB24 окт. 2012 г., 19:32
+1 за ссылку на эту статью. Я'мы задавались вопросом, почему не былоt реализация LINQ для ForEach, но это имеет смысл.
 devdigital24 окт. 2012 г., 19:24
ForEach неt определен как метод расширения IEnumerable <T> и, следовательно, нетт часть LINQ.

Попробуй это -

donations.ForEach(x =>
         {
             int index = donations.IndexOf(x);
             nvc.Add("item_name_" + index, x.AccountName);
         });
 Rohit Vats24 окт. 2012 г., 19:38
Итак, есть ли другой способ найти индекс без создания промежуточной коллекции?
 Rohit Vats24 окт. 2012 г., 19:40
@ Севи - Упс .. !! Да, теперь это имеет смысл для меня. Просто полностью забудь уникальность. Downvotes приняты с честью сейчас. :)
 Servy24 окт. 2012 г., 19:37
Что произойдет, если элемент будет в списке несколько раз? (Обратите внимание, что в ОП 'с кодом все элементы идентичны.)непросто о ужасном спектакле в конце концов; это недажеРабота.
 Austin Salonen24 окт. 2012 г., 19:35
Вы'лучше перечислить промежуточную коллекцию с индексами (а-ля @lc 'ответ) чем поиск в списке на каждой итерации ().IndexOf
 Rohit Vats24 окт. 2012 г., 19:41
@Sevy - Да, спасибо, теперь Servy понял ...Вот почему я сказал, по крайней мере, скажи мне, где я не прав.
 Servy24 окт. 2012 г., 19:40
@ RV1987 Конечно. Использоватьfor петля, как это сделано в OP 'с кодом. Или вы могли бы сделатьForEach метод, который предоставляет индекс, как показывает мой ответ, или вы можете создать целое числоcount и увеличивайте его сами в цикле.

Если вы действительно хотите использовать List.ForEach,все просто:

//[...]
int i=0;
donations.ForEach(x => nvc.Add("item_name_" + i++, x.AccountName);

Мне нравится делать это следующим образом:

NameValueCollection nvc = new NameValueCollection();

List donations = new List();
donations.Add(new BusinessLogic.Donation(0, "", "", ""));
donations.Add(new BusinessLogic.Donation(0, "", "", ""));
donations.Add(new BusinessLogic.Donation(0, "", "", ""));

Enumerable
    .Range(0, donations.Count())
    .ToList()
    .ForEach(i => nvc.Add("item_number_" + i, donations[i].AccountName));

Это's немного запутанный и создает промежуточную коллекцию, но как насчет:

donations.Select((x, i) => new {Name = "item_name_" + i, x.AccountName})
    .ToList()
    .ForEach(x=> nvc.Add(x.Name, x.AccountName));

Это используетперегрузкаEnumerable.Select который включает в себя индекс.

Я должен утверждать, что на самом деле ничего не получится от этого. Вы создаете больше накладных расходов с промежуточной коллекцией, и ИМХО теряет читабельность по сравнению с исходным циклом for.

Вы также можете пропустить промежуточную коллекцию, еслиготов использоватьforeach цикл вместоList.ForEach, Увидеть@wageoghe»ответ (снова настоятельно рекомендуется).

Это старый пост, но он высоко оценен Google, поэтому я подумал, что подойдет более общий подход. (Также я склонен забывать, как это делается, а это значит, что мне приходится каждый раз гуглить ...)

Предположим список целых чисел:

var values = new List() { 2, 3, 4, 0x100, 74, 0xFFFF, 0x0F0F };

Чтобы перебрать список и иметь индекс, сделайте следующее:

values.Select((x, i) => new
{
    item = x,
    index = i
})
.ToList()
.ForEach(obj =>
{
    int value = obj.item;
    int valueIndex = obj.index;
});

Есть ли причина, по которой выне использоватьDictionary как ваши имена / ключи кажутся уникальными? Это было бы быстрее, и вы могли бы использоватьToDictionary стандартный оператор запроса.

Кроме того, если вы хотите использовать метод расширения (хотя Servy говорит, что цикл for является правильным решением), то вы можете написать свой собственный - см.Вот.

Спекуляция на ответ @lc.

foreach (var x in donations.Select((d, i) => new {ItemName = "item_name_" + i, AccountName = d.AccountName}))
{
  nvc.Add(x.ItemName, x.AccountName);
}

Ваш ответ на вопрос