2009-07-29 21 views
101

在ASP.NET C#從列表中選擇多個字段我有一個結構:Linq中

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

,我有那些的名單。我想選擇category_idcategory_name,運行DISTINCT,最後選擇。

這是我現在有:

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

這顯然只是獲取類別名稱。我的問題是,如何獲得多個字段,以及將數據結構存儲在哪個數據結構中(而不是string[])?

編輯

使用結構列表不是一成不變的。如果改變我的支持數據結構以使選擇更容易(我會寫很多這些),那麼我很樂意接受建議。

+8

雖然這是與LINQ方面無關,我會強烈建議你不要使用可變結構或公共字段。就我個人而言,我很少創建結構,但可變的結構只是要求麻煩。 – 2009-07-29 21:00:23

+0

@Jon Skeet謝謝。我會把它轉換成一個有私人成員的普通班級。 – Chet 2009-07-29 21:04:45

+1

@Jon Skeet爲什麼? – Midhat 2010-05-28 11:25:57

回答

175

匿名類型允許您選擇任意字段到數據結構是強類型後來在你的代碼:

​​

既然你(顯然)需要將其存儲FO [R以後使用,你可以使用的GroupBy運算符:

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

你可以使用匿名類型:

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

編譯器將生成的一類代碼namecategory_name性能,並返回該類的實例。您也可以手動指定屬性名稱:

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

您可以擁有任意數量的屬性。

3
var result = listObject.Select(i => new{ i.category_name, i.category_id }) 

這使用匿名類型,所以你必須var關鍵字,因爲表達式的結果類型是事先不知道的。

5

這是anonymous types非常適合的任務。您可以返回由編譯器自動創建並根據使用情況推斷的類型的對象。

的語法是這樣的形式:

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(); 
22
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安永!

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

您可以使用LINQ選擇選擇在各種實例中,這將返回作爲一個匿名類型上面顯示多個字段。如果你想避免這種匿名類型,這是一個簡單的技巧。

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

我認爲這能解決你的問題

2

你可以把它一個KeyValuePair,所以它會返回一個"IEnumerable<KeyValuePair<string, string>>"

所以,這將是這樣的:

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