使用逗号分隔符将IEnumerable转换为字符串?

66
我有一个返回的DataTable
IDs
,1
,2
,3
,4
,5
,100
,101

我想将这个转换为单一字符串值,即:

,1,2,3,4,5,100,101

如何重写以下代码以获得单个字符串

var _values = _tbl.AsEnumerable().Select(x => x);

请查看此链接:http://msdn.microsoft.com/zh-cn/library/a8ycds2f(VS.80).aspx - sjjoshi
2
不清楚 - 返回哪些数据?您是否拥有DataRows和ID列?此外,逗号存在的方式可能会引起混淆 - 它们是否存在于数据库中并且已经存在,还是应该将它们添加进去? - Kobi
感谢所有善良的人。 - user160677
5
“Select(x => x);”这句话毫无意义,特别是在你的情况下。 - abatishchev
1
这个回答解决了你的问题吗?如何将IEnumerable<string>转换为一个逗号分隔的字符串? - StayOnTarget
7个回答

161
var singleString = string.Join(",", _values.ToArray() );

1
你需要在 _values 上调用 ToArray() 吗? - Alex Humphrey
3
最简单的解决方案是,我正要回答,但你需要在_values后面添加.ToArray()。 - Julien N
@ck 这取决于输入数据的确切情况。如果逗号已经在数据中,则只需将“,”替换为String.Empty即可。 - Julien N
@Julien N - 我只是在回报你的恩情,不过我的答案会产生正确的结果... - cjk
3
我猜这是解释上的差异。我认为逗号只是原始问题格式上的一部分,不是数据的一部分。无论如何,使用 string.Join 可能是实现所需结果最简单的方法。 - Winston Smith
28
在 .Net 4 中,JoinConcat 接受 IEnumerable,并且您不需要使用ToArray。因此,这取决于情况。 - Kobi

12

编写一个扩展方法,例如:

public static String AppendAll(this IEnumerable<String> collection, String seperator)
{
    using (var enumerator = collection.GetEnumerator())
    {
        if (!enumerator.MoveNext())
        {
            return String.Empty;
        }

        var builder = new StringBuilder().Append(enumerator.Current);

        while (enumerator.MoveNext())
        {
            builder.Append(seperator).Append(enumerator.Current);
        }

        return builder.ToString();
    }
}

假设你之前的表达式返回的是 IEnumerable<String>,那么调用以下代码:

var _values = _tbl.AsEnumerable().Select(x => x).AppendAll(String.Empty);    

1
为什么要投反对票 - 我知道里面可能有一些不必要的额外东西,但它确实可以运行。 - Alex Humphrey
@Alex - 这个框架有 string.Join 方法,你可能会觉得很有用。请参见 http://msdn.microsoft.com/zh-cn/library/57a79xd0.aspx - Winston Smith
3
@Winston: 我知道String.Join的存在,如果数据来源是数组,我当然会使用它。String.Join需要一个数组,这个数组必须完全保存在内存中,然后再将数组复制到String中,同样也是在内存中完成。因此,String.Join的内存需求要比我所写的代码更多,我所写的代码是逐一迭代序列中的项,并将它们附加到字符串中。String.Join是另一种涉及内存需求/复杂度权衡的方法。 - Alex Humphrey
2
Alex - 你这方面有点过时了:http://msdn.microsoft.com/en-us/library/dd992421.aspx 。而且,想要优化性能还为时过早,尤其是在没有进行剖析的情况下。如果所涉及的数据非常小或已经在一个数组中,那该怎么办呢? - Kobi
1
@Kobi - 我只是在讨论可能的权衡,以及为什么我的方法仍然是有效的。我想 .NET 4.0 中的 String.Join 接受可枚举对象这一事实证明比我更聪明的人也同意我的观点。 - Alex Humphrey
显示剩余2条评论

5
 String.Join(
      ",",
      _tbl.AsEnumerable()
          .Select(r => r.Field<int>("ID").ToString())
          .ToArray())

4
尝试这个:
var _values = _tbl.AsEnumerable().Select(x => x);
string valueString = _values.ToList().Aggregate((a, b) => a + b);

你忘记了分隔符。a + separator + b - Adrian Godong
2
OP不需要分隔符。 - cjk
3
为什么要两步操作并调用 ToList?为什么不直接使用 _tbl.AsEnumerable().Select(x => x).Aggregate((a, b) => a + b); - Kent Boogaart
从理论上讲是正确的,但实际上存在一些错误。Select(x => x) 没有意义,因为 AsEnumerable() 已经将表格转换为 IEnumerable<DataRow>ToList() 没有意义,Aggregate()IEnumerable<T> 的成员而不是 List<T> - abatishchev
而对于字符串 a + b,它绝对不是处理器/内存性能高效的(每次迭代都会创建一个新的字符串)。 - Julien N
显示剩余2条评论

3

我曾遇到过与一般的Array类型类似的问题,并通过以下方式解决:

string GetMembersAsString(Array array)
{
    return string.Join(",", array.OfType<object>());
}

请注意,调用 OfType<object>() 是必需的。

2
你可以使用 MoreLINQ 扩展。
var singleString = _values.ToDelimitedString(",");

0

你可以用这个来作弊:

String output = "";
_tbl.AsEnumerable().Select(x => output += x).ToArray(); 
// output now contains concatenated string

请注意,需要使用ToArray()或类似的方法来强制执行查询。

另一个选项是

String output = String.Concat(_tbl.AsEnumerable().Select(x=>x).ToArray());

@Winston - 不需要分隔符,请重新阅读问题。 - cjk
第二个选项:String output = String.Concat(_tbl.AsEnumerable().ToArray()); 也可以做到同样的效果,对吧?(没有 Select - Julien N

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接