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