Вопрос по lambda, stringbuilder, linq, c# – LINQ для добавления к StringBuilder из String []

6

У меня есть массив строк, который я хочу добавить к строителю строк с помощью LINQ.

В основном я пытаюсь сказать: «Для каждого элемента в этом массиве добавьте строку в этот StringBuilder».

Я могу сделать это довольно легко, используя цикл foreach, однако следующий код, похоже, ничего не делает. Чего мне не хватает?

stringArray.Select(x => stringBuilder.AppendLine(x));

Где как это работает:

foreach(String item in stringArray)
{
  stringBuilder.AppendLine(item);
}
Да, это...msdn.microsoft.com/en-us/library/zecdkyw2.aspx :) sebagomez
Я переименовал StringBuilder и StringArray, чтобы использовать первый символ нижнего регистра. Просто чтобы было ясно, что я ссылаюсь на переменные экземпляра, а не на типы. Jamie Dixon
я бы не использовал команду .Select ... не доступна ли команда ForEach? sebagomez

Ваш Ответ

3   ответа
4

Используйте метод расширения «ForEach» вместо «Select».

stringArray.ForEach(x => stringBuilder.AppendLine(x));
-1
stringArray.DoForAll(x => StringBuilder.AppendLine(x));

Где,DoForAll это метод расширения:

public static class CommonExtensions 
{ 
    public static void DoForAll<T>(this IEnumerable<T> items, Action<T> action) where T: class 
    { 
        if (action == null) 
            throw new ArgumentNullException("action"); 
        foreach (var item in items) 
            action(item);   
    }
} 
@vladhorby: один взгляд на почемуDoForAll и другие эквивалентные расширения не реализованы:blogs.msdn.com/ericlippert/archive/2009/05/18/... jason
Извините, у меня такой метод расширения так долго, я забыл, что это не часть фреймворка. public static class CommonExtensions {public static void DoForAll <T> (это IEnumerable <T> items, действие <T> action), где T: class {if (action == null) throw new ArgumentNullException ("action"); foreach (var item in items) действие (item); }} vladhorby
Что такоеDoForAll? jason
18

StringBuilder builder = StringArray.Aggregate(
                            new StringBuilder(),
                            (sb, s) => sb.AppendLine(s)
                        );

В качестве альтернативы, какЛюк указал в комментарии на другой пост, можно сказать,

Array.ForEach(StringArray, s => stringBuilder.AppendLine(s));

Причина того, чтоSelect не работает, потому чтоSelect для проектирования и созданияIEnumerable проекции. Итак, строка кода

StringArray.Select(s => stringBuilder.AppendLine(s))

не перебираетStringArray призваниеstringBuilder.AppendLine(s) на каждой итерации. Скорее, это создаетIEnumerable<StringBuilder> это можно перечислить.

Я полагаю, что вы могли бы сказать,

var e = stringArray.Select(x => stringBuilder.AppendLine(x));
StringBuilder sb = e.Last();
Console.WriteLine(sb.ToString());

но это действительно отвратительно

Last () гарантированно повторяется? Вместо того, чтобы просто получить stringArray [stringArray.count-1]? Я думаю, что я бы предпочел ToList (); Taemyr
Спасибо Джейсон. Ваш ответ объясняет, почему метод Select не достиг желаемого результата и почему foreach работал. Я буду придерживаться foreach. Мне было просто любопытно, чего мне не хватало. Теперь я знаю. Jamie Dixon

Похожие вопросы