【问题标题】:How to make a natural-looking list?如何制作一个看起来自然的列表?
【发布时间】:2023-04-01 17:15:02
【问题描述】:

所谓自然,我的意思是:

item1、item2、item3 和 item4。

我知道你可以用string.Join 做一个逗号分隔的列表,比如

项目1,项目2,项目3,项目4

但是你怎么能做出这样的列表呢?我有一个基本的解决方案:

int countMinusTwo = theEnumerable.Count() - 2;
string.Join(",", theEnumerable.Take(countMinusTwo)) + "and " 
    + theEnumerable.Skip(countMinusTwo).First();

但我很确定有更好的(如更有效的)方法来做到这一点。任何人?谢谢。

【问题讨论】:

  • 那么输出会是什么样子?
  • @Tigran 输出在顶部。第一个报价块。 =)
  • 你的代码不会产生"item1, item2 and item3."吗?
  • @Tim - oxford comma 的使用有待讨论。
  • @Tim - 那么,在这种情况下,什么是“自然”或不是“自然”是非常主观的。即使我同意,像这样的逗号也是合乎逻辑的,“自然”是每个人最习惯的。所以没有上下文,不使用它不能简单地称为“不正确”。

标签: c# linq list join


【解决方案1】:

您应该计算一次大小并将其存储在变量中。否则每次都会执行查询(如果它不是集合)。此外,如果您想要最后一项,Last 更具可读性。

string result;
int count = items.Count();
if(count <= 1)
    result = string.Join("", items);
else
{
    result = string.Format("{0} and {1}"
        , string.Join(", ", items.Take(counter - 1))
        , items.Last());
}

如果可读性不太重要并且序列可能很大:

var builder = new StringBuilder();
int count = items.Count();
int pos = 0;
foreach (var item in items)
{
    pos++;
    bool isLast = pos == count;
    bool nextIsLast = pos == count -1;
    if (isLast)
        builder.Append(item);
    else if(nextIsLast)
        builder.Append(item).Append(" and ");
    else
        builder.Append(item).Append(", ");
}
string result = builder.ToString();

【讨论】:

  • 我将其归类为“更好”,因为它更易于阅读且效率更高
  • @newStackExchangeInstance:如果您进行扩展,您可以为后缀添加可选参数(“and”、“or”等)。
【解决方案2】:

我会使用字符串。

假设你有:

string items = "item1, item2, item3, item4";

那么你可以这样做:

int lastIndexOf = items.LastIndexOf(",");
items = items.Remove(lastIndexOf);
items = items.Insert(lastIndexOf, " and");

【讨论】:

  • 如果他只有"item1"怎么办
  • lastIndexOf 将返回 -1。处理它。
  • 快。有人计算复杂度! ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 2021-04-15
  • 2018-09-09
  • 2020-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多