【问题标题】:Comma separated list with "and" in place of the last comma逗号分隔列表,用“and”代替最后一个逗号
【发布时间】:2012-12-16 21:35:27
【问题描述】:

我想在 C# 中创建一个逗号分隔的列表,最后一个分隔符是“and”。

string.Join(", ", someStringArray)

会产生这样的字符串

Apple, Banana, Pear

但我希望它看起来像这样:

Apple, Banana and Pear

有没有一种简单的方法可以通过 Linq 和 使用循环来实现它?

【问题讨论】:

  • 项目是否必须按照它们当前的顺序出现,或者我们可以重新排列它们吗?
  • 它们的顺序应该相同。
  • and without using loops - 正如答案所证明的那样,您不需要明确的循环。然而,循环并不邪恶,LINQ 实际上只是为您生成循环。
  • 如果您要求在没有循环的情况下执行此操作,您将得到不可读的答案。
  • 我知道 Linq 内部会生成循环。但是,从可读性的角度来看,我发现 Linq 更好。一旦你进入了 LinqToSql,你就不能没有它了 ;)

标签: c# string linq list


【解决方案1】:

您可以对除最后一项以外的所有项目进行联接,然后手动添加最后一项:

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();
  • 我宁愿使用string, string[], int, int 重载而不是IEnumerable&lt;string&gt; 重载。
  • 如果数组有一项,你会得到一个空字符串。
  • @juharr nope.. 我已经测试过了。对于一个项目,它只显示该项目。不添加“,”或“和”。
【解决方案2】:

一种可能的解决方案:

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

请注意,如果没有实现ICollection&lt;string&gt;(列表和数组实现它),该语句可以多次迭代someStringArray。如果是这样,请使用您的集合创建一个列表并对其执行查询。

【讨论】:

  • 完美适用于 0、1 和 2+ 个条目。不错!
  • @JonB:“完美地处理 0 个条目”是什么意思。应该怎么办?
  • @MarkByers - 它返回“”,而不是导致异常或返回“,”或“and”之类的内容。
【解决方案3】:

有没有一种简单的方法可以使用 Linq 而不使用循环来实现它?

没有循环是不可能的。 For 循环效果最好。 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;
    }

【讨论】:

  • 好吧,如果列表足够长,多个循环可能会出现性能问题。由于大约有 5 个条目,因此性能无关紧要。我使用 Linq 的原因是为了避免意大利面条式代码。这个项目大约有 10 个人在工作,所以我们不能像这样用性能换取可读性。不过谢谢你的回答。
  • @Devils,如果有多个条目使用StringBuilder 而不是String。否则,这是比任何其他 LINQ 查询最有效的解决方案。我总是尝试在 LINQ 中做所有事情(因为它是可读的),但是当性能问题出现时,使用 LINQ 很容易编写最糟糕的代码>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 2022-12-13
  • 2013-08-30
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多