C# 确定c中集合的最后一行#

C# 确定c中集合的最后一行#,c#,arrays,collections,foreach,C#,Arrays,Collections,Foreach,快速问题: 我通过迭代集合并使用字符串生成器来构建JSON字符串(是的,可能有更聪明的方法来实现这一点,但调试linq让我头疼)。当我构建一个数组时,我必须在每个项目后面加一个逗号 目前,我通过在foreach中处理每一行之前增加一个int来实现这一点,如果int与集合中的行数匹配,我不会添加逗号 StringBuilder bob = new StringBuilder(); int i = 0; foreach(Item m in Rows){ i++; bob.Appe

快速问题:

我通过迭代集合并使用字符串生成器来构建JSON字符串(是的,可能有更聪明的方法来实现这一点,但调试linq让我头疼)。当我构建一个数组时,我必须在每个项目后面加一个逗号

目前,我通过在foreach中处理每一行之前增加一个int来实现这一点,如果int与集合中的行数匹配,我不会添加逗号

StringBuilder bob = new StringBuilder();
int i = 0;
foreach(Item m in Rows){
     i++;
     bob.Append(string.Format("{{ foo: '{0}', bar: '{1}' }}", m.foo, m.bar));
     bob.Append(i == Rows.Count() ? "" : ",")
}
我想知道是否有更聪明的方法来确定当前对象是否是集合中的最后一个

更新:


回答。很遗憾我只能选一个,因为有很多好的答案。特别是Matthew Watson的回答可能与我最初想要的最接近——一种直接询问收藏是否是最后一件物品的方式。然而,在回顾所有其他答案时,我认为String.Join更好,用Linq替换foreach也更好。谢谢大家的帮助

我通常跟踪第一项,并在循环的开头包含逗号

bool first = true;
foreach (var item in items)
{
    if (first)
    {
        sb.Append(',');
        first = false;
    }

    sb.Append(item);
}
请注意,上述内容可以转换为:

sb.Append(string.Join(",", items));
编辑添加代码后,可以将循环更改为一条语句:

String bob = string.Join(",", Rows.Select(r => string.Format("{{ foo: '{0}', bar: '{1}' }}", r.foo, r.bar)));
看起来您正试图写出JSON。有一些库可能值得一看。

为什么不使用a来连接逗号呢?编辑:由于您现在已经添加了代码,我看到您已经在使用
StringBuilder
,因此这是可行的:

StringBuilder bob = new StringBuilder();
foreach(Item m in Rows)
{
     bob.Append(string.Format("{{ foo: '{0}', bar: '{1}' }}", m.foo, m.bar));
}
if(bob.Length != 0) bob.Length -= 1;
另一种方法是使用:

你可以用这个

它使用传入分隔符连接传入的字符串数组,最后一个值省略它

比如:

var vals = string.Join(",", Rows.Select(
                              i => string.Format(
                                      "{{ foo: '{0}', bar: '{1}' }}", 
                                      i.foo, 
                                      i.bar)));

假设每行有一个项目可以执行

jsonString.ReplaceAll("\n",",");

已经有很多好的答案了,但我只想提到一个有用的通用类,它可以帮助解决这个问题和许多相关的问题

用于查询枚举数以查找其索引以及它是枚举中的第一项还是最后一项。()

使用SmartEnumberable,代码如下所示:

var result = new StringBuilder();

foreach (var item in data.AsSmartEnumerable())
{
    result.Append(item.Value);

    if (!item.IsLast)
    {
        result.Append(", ");
    }
}
或:


一点代码将有助于提供答案。第一种方法似乎与计算行数基本相同。也许再多一点efficient@roryok,是的,如果这很重要的话,它可以更有效率。您的代码每次都调用Count()。我要指出,只有当我不能使用Join时,我才会使用这种方法。通常,如果性能很重要,我会避免分配大字符串并直接写入流。创建所有这些临时字符串并收集它们是浪费时间的。谢谢drew,您的纯linq实现非常干净,但我的实际foreach比这个简单的示例更复杂,并且随后的linq会伤害我的大脑,只是试图读取它。@roryok,我也这么认为,这就是为什么我在原始答案中包含了一个循环。有点像做一个子串?看来icky@roryok:这是删除最后一个字符的有效且可读的方法。
子字符串
有所不同,它容易出错(索引错误)且可读性较差。string.Join似乎是最干净的方法(每个人都建议这样做),但这意味着我必须在加入之前将项目添加到集合中。哦,好吧。也许是最好的@roryok-
string.Join(“,”,Rows.Select(string.Format…)
但是我又回到了linq领域,那里的诱惑是完全放弃foreach而使用纯linq。是的,只要你有一个可以使用的IEnumerable,你就不需要一个单独的集合。@roryok-LINQ不是万能的,但有时它确实会让生活更轻松。json值中可以有新行,它们仍然有一个可以过滤掉的多代码字符行终止符。仅仅因为你看不到它并不意味着它不在那里。让我们不要进入任何宗教辩论;)
var result = new StringBuilder();

foreach (var item in data.AsSmartEnumerable())
{
    result.Append(item.Value);

    if (!item.IsLast)
    {
        result.Append(", ");
    }
}
foreach (var item in data.AsSmartEnumerable())
{
    if (!item.IsFirst)
    {
        result.Append(", ");
    }

    result.Append(item.Value);
}