从List<int>返回字符串的最优雅方法

12

什么是从List返回一个字符串的最优雅的方法?

好的,是的,我知道我可以做这样的事情:

public string Convert(List<int> something)
{
    var s = new StringBuilder();
    foreach(int i in something)
        s.AppendFormat("{0} ", i);

    return s.ToString();
}

但我确信可以使用Lambda表达式来做到这一点。我也尝试将其附加到StringBuilder中,但它没有达到预期的效果。


爱因斯坦不是曾经说过什么关于优雅的话吗?我死活想不起来了! - Ash
1
如果你想描述真相,那就把优雅留给裁缝。 - Marc Gravell
9个回答

25

在我看来,你最好使用原始版本;LINQ很好,但它并不能解决所有问题。特别是string.Join方法需要一个额外的数组(收益微小),而Aggregate方法使用了大量的中间字符串。

也许可以将其作为扩展方法,但不要使用Format操作:

public static string Concatenate<T>(this IEnumerable<T> source, string delimiter)
{
   var s= new StringBuilder();
   bool first = true;
   foreach(T t in source) {
      if(first) {
        first = false;
      } else {
        s.Append(delimiter);
      }
      s.Append(t);
   }    
   return s.ToString();
}

6
有趣的是,如果.NET提供了一个内置函数,比如叫做ListToString,然后有人回答说:“只需使用ListToString”,那么每个人都会称其为优雅的。但是如果有人编写了一个在内部执行完全相同的操作的函数,仅凭代码就会被认为是笨拙的。LINQ看起来很简洁,但这并不意味着在幕后没有大量工作正在进行。 - Dan Tao
2
@Dan - 说得好。的确,LINQ 的很多部分都是关于隐藏复杂性的——当然,复杂性仍然存在 ;-p。 - Marc Gravell
“Aggregate”方法和LINQ是什么意思? - PositiveGuy
1
人们会称之为笨拙,因为这些低级技巧本来就是笨拙的。这就是为什么我们有了LINQ等工具。如果我们想一直处理这样的决策,而不是只在特殊情况下偶尔出现,那么我们可能会使用一种不以VM字节码形式运行的语言。在99%的所有应用程序中,使用LINQ方法更易读、易维护,而且很多时候甚至比自己编写的代码还要快。 - sara

21
String result = String.Join(" ", list.Select(item => item.ToString()).ToArray());

如果它只是一个类型为List<int>(而不是List<int?>)的集合,那么其中可能只有0而没有NULL。

但是,为了解决假设情况或更一般的null问题,可以添加一个Where(item => item != null),使用条件运算符或空值合并运算符。但是,每个添加到表达式中的“修复”都会使其更难以阅读和优雅。


4
抱歉,请问这有什么优雅之处?仅因为它是新的和Linq式的并不意味着它自动具有优雅性。顺便说一句,我喜欢使用Linq,只是不是用于所有事情。 - Ash
1
那可能很重要。聚合+字符串生成器可能会更好。 - Dykam
它很优雅,因为它简单而紧凑。显然,这不是最好的或最高效的解决方案。而且我完全忽略了空指针问题。 - Daniel Brückner
它也很“优雅”,因为它使用了现有的String.Join()。这个事实立即向未来的读者传达了很多信息,而自己编写循环的方法则不会这样做。 - StayOnTarget

12
使用string.Join:
string.Join(" ", something.Select(i => i.ToString()).ToArray())

7

使用 string.Join

List<int> data = ..;
var result = string.Join(";", data); // (.NET 4.0 only)
var result = string.Join(";", data.Select(x => x.ToString()).ToArray()); // (.NET 3.5)

4

又一个扩展方法:

public static class Extensions {
    public static string Join(this List<int> list) {
        return string.Join(" ", list.Select(item => item.ToString()).ToArray());
    }
}

用法:

string s = new List<int> {1, 2, 3}.Join();

1

充分利用StringBuilder和LINQ:

    public static string SpaceOut(this IEnumerable<int> list)
    {
        if (list.Count()==)) return string.Empty;

        var res = new StringBuilder();

        list.Take(list.Count() - 1).ToList().ForEach(i => res.Append(i.ToString() + " "));
        res.Append(list.Last().ToString());

        return res.ToString();
    }

0
string result = list.Aggregate("", (str, i) => str + " " + i).TrimStart(' ');

你需要在lambda中将i转换为字符串。 - Richard
实际上你不需要;这是C#的隐含意义。 - Jason

0

使用LINQ和累加:

string res = list.Select(x => x.ToString()).Aggregate("", (a,b) => a + " " + b);

并保存一个中间数组(但对于大型列表,会创建O(n)的垃圾字符串)。


0
实现一个类似这样的可枚举扩展:
public static class EnumerableExtensions{
   public static string JoinStrings<TItem>(this IEnumerable<TItem> sequence, string separator)
   {
      return sequence.JoinStrings(separator, (TItem item) => item.ToString());
   }
}

然后在 IEnumerables 上像这样使用它:
var myList = new List<int>() {1,2,3,4};
var myString = myList.JoinStrings(", ");

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