在Linq中从列表中select多个字段

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

public struct Data { public int item1; public int item2; public int category_id; public string category_name; } 

我有一个列表。 我想selectcategory_idcategory_name ,运行DISTINCT ,最后在ORDERBY上运行ORDERBY

这是我现在拥有的:

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

这显然只是获得类别名称。 我的问题是,我怎么得到多个字段,我将什么数据结构存储(不是一个string[] )?

编辑

使用结构列表并不是一成不变的。 如果最好改变我的支持数据结构,使select更容易(我会写很多这些),那么我很乐意采取build议。

匿名types允许您将任意字段select为稍后在代码中强types化的数据结构:

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

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

 Data[] cats = listObject .GroupBy(i => new { i.category_id, i.category_name }) .OrderByDescending(g => g.Key.category_name) .Select(g => g.First()) .ToArray(); 
 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); 

编辑 :让它更LINQ-ey!

你可以使用匿名types:

 .Select(i => new { i.name, i.category_name }) 

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

 i => new { Id = i.category_id, Name = i.category_name } 

你可以有任意数量的属性。

这是匿名types非常适合的任务。 您可以返回由编译器自动创build的types的对象,根据使用情况推断。

语法是这种forms:

 new { Property1 = value1, Property2 = value2, ... } 

对于你的情况,请尝试如下所示:

 var listObject = getData(); var catNames = listObject.Select(i => new { CatName = i.category_name, Item1 = i.item1, Item2 = i.item2 }) .Distinct().OrderByDescending(s => s).ToArray(); 
 var result = listObject.Select( i => new{ i.category_name, i.category_id } ) 

这使用匿名types,所以你必须var关键字,因为expression式的结果types是事先不知道的。

 (from i in list select new { i.category_id, i.category_name }) .Distinct() .OrderBy(i => i.category_name); 

您可以使用linqselect多个字段如上所示,在各种示例中,这将作为匿名types返回。 如果你想避免这个匿名types这里是简单的伎俩。

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

我认为这解决了你的问题

你可以使它成为一个KeyValuePair,所以它会返回一个"IEnumerable<KeyValuePair<string, string>>"

所以,这将是这样的:

 .Select(i => new KeyValuePair<string, string>(i.category_id, i.category_name )).Distinct();