另一个Linqification问题

时间:2009-12-17 04:40:09

标签: c# linq

假设我有一个对象列表,并且该对象具有字符串属性。我想得到一个逗号分隔的列表,列出列表中每个对象的每个字符串属性的值。 这是一种方法(sans linq)


StringBuilder result = new StringBuilder()
foreach(myObject obj in myList)
{
  result.Append(obj.TheString);
  result.Append(", ");
}
// then trim the trailing ", " and call ToString() on result, etc, etc...

这是我在linqification的第一次拍摄。还有更好的方法吗?


string result = string.Join(", ", myList.Select(myObj => myObj.TheString).ToArray());

这是一行代码,但它对我来说效率不高 - 迭代列表只是为了构建一个数组,只是迭代数组并构建一个字符串......哇!

有更好的方法吗?

4 个答案:

答案 0 :(得分:5)

如果您想要高效,请将Enumerable.AggregateStringBuilder一起使用:

string result = myList.Aggregate(new StringBuilder(),
                                 (sb, o) => sb.Append(o.TheString).Append(", "))
                      .ToString();

最初的问题是String.Join想要一个数组。在.NET 4中,会有一个需要IEnumerable<string>的重载(我希望它会像上面那样实现)。

答案 1 :(得分:1)

我喜欢这种加入字符串的扩展方法。它基本上与您使用的技术相同,但包含在扩展方法中。因为效率不是目标所以我不建议大型套装。对我来说,好处是表现力(非常有用),方便小集:

[Test]
public void Should_make_comma_delimited_list()
{
    var colors = new List<HasColor>
    {
        new HasColor { Color = "red" },
        new HasColor { Color = "green" },
        new HasColor { Color = "blue" }
    };

    var result = colors.Implode(x => x.Color, ", ");

    Assert.That(result, Is.EqualTo("red, green, blue"));
}

public class HasColor
{
    public string Color { get; set; }
}

public static class LinqExtensions
{
    public static string Implode<T>(this IEnumerable<T> list, Func<T, string> func, string separator)
    {
        return string.Join(separator, list.Select(func).ToArray());
    }
}

答案 2 :(得分:1)

使用string.Join,这已经足够了。

在分析器告诉您这样做时进行优化。

使用StringBuilder的版本的可读性很差,你仍然得到你的尾随逗号。

答案 3 :(得分:0)

这是另一种方式(resultStringBuilder):

myList.ForEach(
    myObj => 
    { 
        if (result.Length != 0) 
            result.Append(","); 
        result.Append(myObj.TheString); 
    }
    );