创建由多个属性值组成的序列

时间:2011-12-31 01:41:39

标签: c# linq linq-to-objects

我有一个现有的对象集合,其中包含两个感兴趣的属性。两种属性都属于同一类型。我想创建一个由属性值组成的新序列。这是一种方式(为了简单起见,我使用的是元组而不是我的自定义类型):

var list = new List<Tuple<string, string>>
    { Tuple.Create("dog", "cat"), Tuple.Create("fish", "frog") };

var result =
    list.SelectMany(x => new[] {x.Item1, x.Item2});

foreach (string item in result)
{
    Console.WriteLine(item);
}

结果:

dog
cat
fish
frog

这给了我想要的结果,但有没有更好的方法来实现这一点(特别是,无需创建数组或集合)?

修改

这也是有效的,代价是迭代两次集合:

var result = list.Select(x => x.Item1).Concat(list.Select(x => x.Item2));

2 个答案:

答案 0 :(得分:2)

我认为你的方法很好,我会坚持这一点。使用SelectMany时,使用数组可以很好地完成工作,最终结果为IEnumerable<string>

有一些替代方法,但我认为它们比你的方法更冗长。

Aggregate方法:

var result = list.Aggregate(new List<string>(), (seed, t) =>
{
    seed.Add(t.Item1);
    seed.Add(t.Item2);
    return seed;
});
result.ForEach(Console.WriteLine);

ForEach方法:

var result = new List<string>();
list.ForEach(t => { result.Add(t.Item1); result.Add(t.Item2); });
result.ForEach(Console.WriteLine);

在这两种情况下都会创建一个新的List<string>

答案 1 :(得分:2)

如果你想避免创建另一个集合,你可以改为产生结果。

void Main()
{
    var list = new List<Tuple<string, string>>
        { Tuple.Create("dog", "cat"), Tuple.Create("fish", "frog") };

        foreach (var element in GetSingleList(list))
        {
            Console.WriteLine (element);
        }
}

// A reusable extension method would be a better approach.
IEnumerable<T> GetSingleList<T>(IEnumerable<Tuple<T,T>> list) {

    foreach (var element in list)
    {
        yield return element.Item1;
        yield return element.Item2;
    }

}