Использование LINQ для объединения строк - PullRequest
315 голосов
/ 20 октября 2008

Какой самый эффективный способ написания старой школы:

StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
    foreach (string s in strings)
    {
        sb.Append(s + ", ");
    }
    sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();

... в LINQ?

Ответы [ 17 ]

5 голосов
/ 03 сентября 2012

Здесь используется чистый LINQ в качестве одного выражения:

static string StringJoin(string sep, IEnumerable<string> strings) {
  return strings
    .Skip(1)
    .Aggregate(
       new StringBuilder().Append(strings.FirstOrDefault() ?? ""), 
       (sb, x) => sb.Append(sep).Append(x));
}

И это чертовски быстро!

5 голосов
/ 20 октября 2008

Существуют различные альтернативные ответы на этот предыдущий вопрос - который, по общему признанию, был целевым массивом в качестве источника, но получил обобщенные ответы.

3 голосов
/ 01 сентября 2011

Я собираюсь немного обмануть и выкинуть новый ответ на этот вопрос, который, кажется, суммирует лучшее из всего, что здесь есть, вместо того, чтобы вставлять его в комментарий.

Таким образом, вы можете в одну строку это:

List<string> strings = new List<string>() { "one", "two", "three" };

string concat = strings        
    .Aggregate(new StringBuilder("\a"), 
                    (current, next) => current.Append(", ").Append(next))
    .ToString()
    .Replace("\a, ",string.Empty); 

Редактировать: Вы либо захотите сначала проверить наличие пустого перечислимого, либо добавить .Replace("\a",string.Empty); в конец выражения. Думаю, я пытался стать слишком умным.

Ответ от @ a.friend может быть немного более производительным, я не уверен, что Replace делает под капотом по сравнению с Remove. Единственное другое предостережение, если по какой-то причине вы хотите объединить строки, заканчивающиеся на \ a, вы потеряете свои разделители ... Я считаю это маловероятным. Если это так, у вас есть другие необычные символы на выбор.

2 голосов
/ 02 февраля 2011

Вы можете комбинировать LINQ и string.join() довольно эффективно. Здесь я удаляю элемент из строки. Есть и лучшие способы сделать это, но вот оно:

filterset = String.Join(",",
                        filterset.Split(',')
                                 .Where(f => mycomplicatedMatch(f,paramToMatch))
                       );
1 голос
/ 22 апреля 2010

Много вариантов здесь. Вы можете использовать LINQ и StringBuilder, чтобы получить производительность, например, так:

StringBuilder builder = new StringBuilder();
List<string> MyList = new List<string>() {"one","two","three"};

MyList.ForEach(w => builder.Append(builder.Length > 0 ? ", " + w : w));
return builder.ToString();
1 голос
/ 14 декабря 2011

При выполнении синтаксического анализа файла журнала IIS с использованием linq я сделал следующее быстро и сработало при 1 миллионе строк (15 секунд), хотя при попытке выполнить 2 миллиона строк произошла ошибка нехватки памяти.

    static void Main(string[] args)
    {

        Debug.WriteLine(DateTime.Now.ToString() + " entering main");

        // USED THIS DOS COMMAND TO GET ALL THE DAILY FILES INTO A SINGLE FILE: copy *.log target.log 
        string[] lines = File.ReadAllLines(@"C:\Log File Analysis\12-8 E5.log");

        Debug.WriteLine(lines.Count().ToString());

        string[] a = lines.Where(x => !x.StartsWith("#Software:") &&
                                      !x.StartsWith("#Version:") &&
                                      !x.StartsWith("#Date:") &&
                                      !x.StartsWith("#Fields:") &&
                                      !x.Contains("_vti_") &&
                                      !x.Contains("/c$") &&
                                      !x.Contains("/favicon.ico") &&
                                      !x.Contains("/ - 80")
                                 ).ToArray();

        Debug.WriteLine(a.Count().ToString());

        string[] b = a
                    .Select(l => l.Split(' '))
                    .Select(words => string.Join(",", words))
                    .ToArray()
                    ;

        System.IO.File.WriteAllLines(@"C:\Log File Analysis\12-8 E5.csv", b);

        Debug.WriteLine(DateTime.Now.ToString() + " leaving main");

    }

Реальная причина, по которой я использовал linq, заключалась в том, что ранее мне требовался Distinct ():

string[] b = a
    .Select(l => l.Split(' '))
    .Where(l => l.Length > 11)
    .Select(words => string.Format("{0},{1}",
        words[6].ToUpper(), // virtual dir / service
        words[10]) // client ip
    ).Distinct().ToArray()
    ;
0 голосов
/ 15 ноября 2009

Я писал об этом некоторое время назад, то, что я сделал швы, чтобы быть именно тем, что вы ищете:

http://ondevelopment.blogspot.com/2009/02/string-concatenation-made-easy.html

В посте блога описывается, как реализовать методы расширения, которые работают в IEnumerable и называются Concatenate, это позволит вам писать такие вещи, как:

var sequence = new string[] { "foo", "bar" };
string result = sequence.Concatenate();

Или более сложные вещи, такие как:

var methodNames = typeof(IFoo).GetMethods().Select(x => x.Name);
string result = methodNames.Concatenate(", ");
...