14

Вопрос по linq, c#, string, list – Разделенный запятыми список с «и» вместо последней запятой

Я хочу создать разделенный запятыми список в C # со словом "а также" как последний разделитель.

string.Join(", ", someStringArray)

приведет к такой строке

Apple, Banana, Pear

но вместо этого я хочу, чтобы это выглядело так:

Apple, Banana and Pear

Есть ли простой способ добиться этого с помощью Linq ибез используя петли?

Если ты'просим сделать это без петель, выВы получите ответы, которые не очень читабельны.

от svick

Они должны быть в том же порядке.

от bytecode77

and without using loops - как доказывают ответы, вы неДля этого не нужны явные циклы. Однако циклы вряд ли являются злом, и LINQ на самом деле просто создает циклы для вас.

от Jon B

Я знаю, что Linq внутренне генерирует петли. Однако с точки зрения читабельности я считаю Linq лучше. Попав в LinqToSql, вы можетене жить без него больше;)

от bytecode77

Должны ли элементы отображаться в том же порядке, в котором они находятся в настоящее время, или мы можем перестроить их?

от Damien_The_Unbeliever
3 ответа
12

Одно из возможных решений:

var items = someStringArray; // someStringArray.ToList() if not a ICollection<>
var s = string.Join(", ", items.Take(items.Count() - 1)) +
        (items.Count() > 1 ? " and " : "") + items.LastOrDefault();

Обратите внимание, что этот оператор может повторятьсяsomeStringArray несколько раз, если это не такреализоватьICollection (списки и массивы реализуют это). Если это так, создайте список со своей коллекцией и выполните запрос по нему.

Ну, на самом деле это не работает с нуля. Работая над этим ...

от digEmAll

Отлично работает с 0, 1 и 2+ записями. Ницца!

от Jon B

@MarkByers - возвращает ""вместо того, чтобы вызывать исключение или возвращать что-то вроде "," или же "а также".

от Jon B

@JonB: Что вы подразумеваете под "отлично работает с 0 записей ", Что должно произойти?

от Mark Byers

Теперь все должно быть в порядке ...

от digEmAll
23

Вы можете выполнить объединение всех элементов

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

using System;
using System.Linq;

namespace Stackoverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            DumpResult(new string[] { });
            DumpResult(new string[] { "Apple" });
            DumpResult(new string[] { "Apple", "Banana" });
            DumpResult(new string[] { "Apple", "Banana", "Pear" });
        }

        private static void DumpResult(string[] someStringArray)
        {
            string result = string.Join(", ", someStringArray.Take(someStringArray.Length - 1)) + (someStringArray.Length <= 1 ? "" : " and ") + someStringArray.LastOrDefault();
            Console.WriteLine(result);
        }
    }
}

Как видите, есть проверка количества товаров и решается,необходимо добавитьа также' часть.

Затем нам нужно использовать это: string days = string.Join (",", notSentDays.Take (notSentDays.Count - 1)) + (notSentDays.Count == 1? "": " а также ") + notSentDays.Last (); I '

от bytecode77

Если в массиве есть один элемент, вы получите пустую строку.

от juharr

Хорошо, но что, если список содержит менее двух элементов?

от Mark Byers

я бы предпочел использоватьstring, string[], int, int перегрузка, чемIEnumerable перегрузки.

от Rawling
2

Есть ли простой способ добиться этого с помощью Linq и без использован

ия циклов?

Без петли невозможно. Для цикла будет работать лучше всего. LINQ-запросы будут использовать несколько циклов.

    string Combine (IEnumerable<string> list)
    {
        bool start = true;
        var last = string.Empty;
        String str = string.Empty;

        foreach(var item in list)
        {
            if ( !start)
            {
                str = str + " , " + item; 
                last = item;

            }
            else
            {
                str = item;
                start = false;
            } 

        }

        if (!string.IsNullOrWhiteSpace(last))
        {
            str = str.Replace( " , " + last, " and " + last);
        }

        return str;
    }
</string>

Очень легко читать и понимать.

от SoftwareCarpenter

Ну, несколько циклов может вызвать проблемы с производительностью, если список был достаточно длинным. Поскольку существует примерно 5 записей, производительность не имеет значения. Причина, по которой я использую Linq, состоит в том, чтобы избегать кода спагетти. Над этим проектом работает около 10 человек, поэтому мы можемобменять производительность на читабельность, как это. Но спасибо за ваш ответ.

от bytecode77

@Devils, если есть несколько записейStringBuilder вместоString, В противном случае это наиболее эффективное решение, чем любое другоеLINQ запрос. Я всегда стараюсь делать все (как доступно для чтения) в LINQ, но когда возникают проблемы с производительностью, легко написать худший код, используя LINQ>

от Tilak

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