从Linq中的列表中选择多个字段

Che*_*het 125 c# linq data-structures

在ASP.NET C#中我有一个结构:

public struct Data
{
    public int item1;
    public int item2;
    public int category_id;
    public string category_name;
}
Run Code Online (Sandbox Code Playgroud)

我有一份清单.我要选择category_idcategory_name,运行的DISTINCT最后一个ORDERBYcategory_name.

这就是我现在拥有的:

List<Data> listObject = getData();
string[] catNames = listObject
                    .Select(i=> i.category_name)
                    .Distinct()
                    .OrderByDescending(s => s)
                    .ToArray();
Run Code Online (Sandbox Code Playgroud)

这显然只是获得了类别名称.我的问题是,我如何获得多个字段,以及将其存储在(不是a string[])中的数据结构?

编辑

使用结构列表并不是一成不变的.如果建议更改我的支持数据结构以使选择更容易(我将写很多这些),那么我很乐意接受建议.

Jas*_*son 215

匿名类型允许您在以后在代码中强类型的数据结构中选择任意字段:

var cats = listObject
    .Select(i => new { i.category_id, i.category_name })
    .Distinct()
    .OrderByDescending(i => i.category_name)
    .ToArray();
Run Code Online (Sandbox Code Playgroud)

由于您(显然)需要存储它以供以后使用,因此您可以使用GroupBy运算符:

Data[] cats = listObject
    .GroupBy(i => new { i.category_id, i.category_name })
    .OrderByDescending(g => g.Key.category_name)
    .Select(g => g.First())
    .ToArray();
Run Code Online (Sandbox Code Playgroud)


IRB*_*BMe 25

var selectedCategories =
    from value in
        (from data in listObject
        orderby data.category_name descending
        select new { ID = data.category_id, Name = data.category_name })
    group value by value.Name into g
    select g.First();

foreach (var category in selectedCategories) Console.WriteLine(category);
Run Code Online (Sandbox Code Playgroud)

编辑:让它更加LINQ-ey!


Meh*_*ari 23

您可以使用匿名类型:

.Select(i => new { i.name, i.category_name })
Run Code Online (Sandbox Code Playgroud)

编译器将为具有namecategory_name属性的类生成代码,并返回该类的实例.您也可以手动指定属性名称:

i => new { Id = i.category_id, Name = i.category_name }
Run Code Online (Sandbox Code Playgroud)

您可以拥有任意数量的属性.


小智 7

您可以使用 linq Select 选择多个字段,如上所示的各种示例,这将作为匿名类型返回。如果你想避免这种匿名类型,这里有一个简单的技巧。

var items = listObject.Select(f => new List<int>() { f.Item1, f.Item2 }).SelectMany(item => item).Distinct();
Run Code Online (Sandbox Code Playgroud)

我认为这可以解决您的问题


Vic*_*tor 7

您可以将其设为 KeyValuePair,因此它将返回"IEnumerable<KeyValuePair<string, string>>"

所以,它会是这样的:

.Select(i => new KeyValuePair<string, string>(i.category_id, i.category_name )).Distinct();
Run Code Online (Sandbox Code Playgroud)


Nol*_*rin 5

这是匿名类型非常适合的任务.您可以返回由编译器自动创建的类型的对象,从使用情况推断.

语法是这种形式:

new { Property1 = value1, Property2 = value2, ... }
Run Code Online (Sandbox Code Playgroud)

对于您的情况,请尝试以下内容:

var listObject = getData();
var catNames = listObject.Select(i =>
    new { CatName = i.category_name, Item1 = i.item1, Item2 = i.item2 })
    .Distinct().OrderByDescending(s => s).ToArray();
Run Code Online (Sandbox Code Playgroud)