C# - 将IEnumerable转换为分隔字符串

21

如何使用函数式编程方法将 IEnumerable<string> 转换为分隔字符串?我知道可以使用循环,但我正在尝试理解函数式编程。

以下是我的示例:

var selectedValues =
from ListItem item in checkboxList.Items
where item.Selected
select item.Value;

var delimitedString = ??

我能否只在第一个变量赋值时完成这个操作(将每个结果附加到前一个结果)?

8个回答

41
string.Join(", ", string[] enumerable)

2
@Lucas,如果你使用的是.NET 4,那就不一样了。http://msdn.microsoft.com/zh-cn/library/dd992421.aspx - Omer Raviv
@Omer,没错!但这是在.NET 4之前的2008年10月发生的 :) - Lucas

24

这是一个使用StringBuilder的示例。好处是Append()返回StringBuilder实例本身。

  return list.Aggregate( new StringBuilder(), 
                               ( sb, s ) => 
                               ( sb.Length == 0 ? sb : sb.Append( ',' ) ).Append( s ) );

最后一行代码应该是 (sb.Length == 0 ? sb.Append(s) : sb.Append(',')) .Append(s)); - Tormod

20
var delimitedString = selectedValues.Aggregate((x,y) => x + ", " + y);

6
在中间字符串方面,这将是非常昂贵的。非常函数式,但不太实用。 http://www.yoda.arachsys.com/csharp/stringbuilder.html - Marc Gravell
4
@Marc,我回答了所问的问题,那是关于FP而不是性能的。 - Ilya Ryzhenkov

4
var delimitedString = string.Join(",", checkboxList.Items.Where(i => i.Selected).Select(i => i.Value).ToArray());

3

AviewAnew是最好的选择,但如果你想学习如何以函数式思维来编程,你应该使用fold操作(在.NET中称为aggregate)。

items.Aggregate((accum, elem) => accum + ", " + elem);

字符串连接使用string.join更好吗?我认为从可读性的角度来看,它更好。 - Jeremy
我会说是的。.ToArray() [获取string[]] 将使用倍增,因此不会有太多中间数组 - 然后string.Join本质上就是StringBuilder; 但是,字符串连接每次都会产生一个新字符串,因此大小会不断变化。 - Marc Gravell
同意,这是您在函数式编程语言(如Haskell)中找到的解决方案类型,但不适用于此处。但掌握foldr是掌握函数式语言的关键之一。 - Santiago Palladino
那么,这是为什么函数式语言通常不太高效的一个例子吗? - Jeremy

2

嗯,在这种情况下,函数式方法可能不是最合适的选择,因为没有LINQ的“ForEach”,而且你不想使用字符串拼接:你需要使用StringBuilder。你可以使用ToArray(上面刚出现了一个例子),但我倾向于简单地使用:

    StringBuilder sb = new StringBuilder();
    foreach(ListViewItem item in checkboxList.SelectedItems) {
        if(sb.Length > 0) sb.Append(',');
        sb.Append(item.Text);
    }
    string s = sb.ToString();

不是函数式编程,但它可以工作... 当然,如果您的源已经是字符串数组,则 string.Join 是完美的选择。 (LINQ 是一个很棒的工具,但不一定适用于每个工作)

1
这是一种使用LINQ/函数式方法来完成的方式。

string[] toDelimit = CallSomeFunction();
return toDelimit.Aggregate((x, y) => x + "," + y);

0

这是3.5兼容的:

var selectedValues = String.Join(",", (from ListItem item in checkboxList.Items where item.Selected select item.Value).ToArray());

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