使用LINQ选择多个字段的简便方法

时间:2014-01-31 15:34:17

标签: c# linq

看看这个示例对象,

public class Demo
{
    public string DisplayName { get; set; }

    public int Code1 { get; set; }

    public int Code2 { get; set; }

    ...
}

并且我想说我想将所有代码(Code1Code2)放在一个列表中(IEnumerable)...这就是一种方式:

var codes = demoList.Select(item => item.Code1).ToList();
codes.AddRange(demoList.Select(item => item.Code2));
//var uniqueCodes = codes.Distinct(); // optional

我知道这不是一个不错的最佳解决方案,所以我很想知道什么是更好的方法/(最佳实践)?

5 个答案:

答案 0 :(得分:6)

SelectMany

怎么样?
var codes = demoList.SelectMany(item => new[] { item.Code1, item.Code2 });

顺便说一下,在LINQ中进行连接的惯用方法是Concat

var codes = demoList.Select(item => item.Code1)          
                    .Concat(demoList.Select(item => item.Code2));

答案 1 :(得分:4)

Linq 银弹来杀死所有东西

为了您的意图,我建议以下

var codes = new List<int>(demoList.Count * 2);
foreach(var demo in demoList)
{
  codes.Add(demo.Code1);
  codes.Add(demo.Code2);
}

<强> BENCHMARK

我做了一个基准测试,用我的解决方案和Ani的

重复了一百万个和一千个实例的列表
  

金额:100万

     

我的:2ms

     

Ani's:20ms

     

金额为1000件

     

我的:1ms

     

Ani's:12ms

示例代码

        List<MyClass> list = new List<MyClass>(1000);
        for (int i = 0; i < 100000; i++)
        {
            list.Add(new MyClass
            {
                Code1 = i,
                Code2 = i * 2,
            });
        }
        System.Diagnostics.Stopwatch timer1 = System.Diagnostics.Stopwatch.StartNew();
        var resultLinq = list.SelectMany(item => new[] { item.Code1, item.Code2 }).ToList();
        Console.WriteLine("Ani's: {0}", timer1.ElapsedMilliseconds);

        System.Diagnostics.Stopwatch timer2 = System.Diagnostics.Stopwatch.StartNew();
        var codes = new List<int>(list.Count * 2);
        foreach (var item in list)
        {
            codes.Add(item.Code1);
            codes.Add(item.Code2);
        }
        Console.WriteLine("Mine : {0}", timer2.ElapsedMilliseconds);
    }

答案 2 :(得分:2)

// this won't return duplicates so no need to use Distinct.
var codes = demoList.Select(i=> i.Code1)
                    .Union(demoList.Select(i=>i.Code2));

在一些评论之后编辑完整性(参见@Ani答案):

// Optionally use .Distinct()
var codes = demoList.Select(i=>i.Code1)
                    .Concat(demoList.Select(i=>i.Code2))
                    .Distinct();

答案 3 :(得分:0)

即使您编写的代码也很完美,我只是给您另一种选择 试试这个

var output = Enumerable.Concat(demoList.Select(item => item.Code1).ToList(), demoList.Select(item => item.Code2).ToList()).ToList();

答案 4 :(得分:0)

路易斯的回答对我来说已经足够了。但我确实重新考虑了它,使用任意数量的字段的扩展方法......并且最佳结果仍然是路易斯的答案。 (100000条记录的例子)

Ani's: 21
Luis: 4
Jaider's: 15

这是我的扩展方法。

public static IEnumerable<T> SelectExt<R, T>(this IEnumerable<R> list, params Func<R, T>[] GetValueList)
{
    var result = new List<T>(list.Count() * GetValueList.Length);
    foreach (var item in list)
    {
        foreach (var getValue in GetValueList)
        {
            var value = getValue(item);
            result.Add(value);
        }
    }

    return result;
}

用法,将是:

var codes = demoList.SelectExt(item => item.Code1, item => item.Code2).ToList();