2012-09-05 34 views
0

可能重複:
Sorting an IEnumerable in LINQ在LINQ排序的IEnumerable

是否可以解決這一個不使用.ToList()?

請參閱下面的代碼。

下面的代碼將產生此輸出。

{ id = 1, name = "sample 1", list = {'a','f','d'}},   
    { id = 5, name = "sample 1", list = {'a','f','c'}}, 
    { id = 2, name = "sample 1", list = {'g','b'}}, 
    { id = 4, name = "sample 1", list = {'i','e','h'}}, 
    { id = 6, name = "sample 1", list = {'d','b','c'}}, 
    { id = 3, name = "sample 1", list = {'h','i','c'}}, 

感謝

RJ

IEnumerable<extra> eList = new List<extra>() 
{ 
    new extra{ id = 1, text = "a"}, 
    new extra{ id = 2, text = "g"}, 
    new extra{ id = 3, text = "i"}, 
    new extra{ id = 4, text = "e"}, 
    new extra{ id = 5, text = "f"}, 
    new extra{ id = 6, text = "d"}, 
    new extra{ id = 7, text = "c"}, 
    new extra{ id = 8, text = "h"}, 
    new extra{ id = 9, text = "b"} 
}; 

IEnumerable<sample> sam = new List<sample>() 
{ 
    new sample{ id = 1, name = "sample 1", list = new List<int>{1,5,6}}, 
    new sample{ id = 2, name = "sample 2", list = new List<int>{2,9}}, 
    new sample{ id = 3, name = "sample 3", list = new List<int>{8,3,7}}, 
    new sample{ id = 4, name = "sample 4", list = new List<int>{3,4,8}}, 
    new sample{ id = 5, name = "sample 5", list = new List<int>{1,5,7}}, 
    new sample{ id = 6, name = "sample 6", list = new List<int>{6,9,7}} 
}; 

var sorted = (from d1 in sam 
       select new 
       { 
        name = d1.name, 
        id = d1.id, 
        list = 
        (
         from d2 in d1.list 
         join e in eList on d2 equals e.id 
         select e.text 
       ).OrderBy(item => item).ToList() 
       }).OrderBy(item => item.list.FirstOrDefault()); 
+3

BTW你的命名約定是痛苦的。 – Stilgar

+0

這只是一個練習....命名不是我在這裏的關注...謝謝 – user1120260

+1

老實說,有一次,我想你想'ToList'在這裏。否則,你的'list'成員包含一個'IEnumerable',而不是'List',並且每次枚舉它時都會重新執行連接。如果您不介意這一點,您可以通過listerally刪除「ToList」調用,並且順序仍然相同。 – Rawling

回答

0

也許ThenBy會做嗎?

var sorted = (from d1 in sam 
       select new 
       { 
        name = d1.name, 
        id = d1.id, 
        list = 
        ( 
         from d2 in d1.list 
         join e in eList on d2 equals e.id 
         select e.text 
       ).OrderBy(item => item 
       }).ThenBy(item => item.list.FirstOrDefault()); 

我誤解了這個問題。爲什麼不只是刪除ToList?您可能想要.ToList(),但每次訪問集合時都要防止排序。

+0

它不起作用...'string'不包含'list'的定義,也沒有接受'string'類型的第一個參數的擴展方法'list'....... – user1120260

+0

哦對。我剛剛編輯。嘗試新的。 – Stilgar

+0

)預計...將其添加到OrderBy()中但出現錯誤...'System.Collections.Generic。IEnumerable '不包含'ThenBy'的定義,並且沒有擴展方法'ThenBy'接受類型'System.Collections.Generic.IEnumerable '的第一個參數 – user1120260

0

我剛剛測試了你的原始代碼,沒有'ToList',它對項目和'extras'進行了排序就好了。你能詳細說明你到底想達到什麼嗎?證明:你的代碼沒有ToList

1 "sample 1" a d f 
5 "sample 5" a c f 
2 "sample 2" b g 
6 "sample 6" b c d 
3 "sample 3" c h i 
4 "sample 4" e h i 

結果:你的原代碼與ToList

結果

1 "sample 1" a d f <-- adf is sorted 
5 "sample 5" a c f <-- also sorted 
2 "sample 2" b g  <-- and here too 
6 "sample 6" b c d <-- yep 
3 "sample 3" c h i <-- it is! 
4 "sample 4" e h i <-- ... 
      ^
       | 
       \ aabbce is sorted, too 

看起來與我:)

至於總體思路,在沒有「ToList」的情況下用LINQ語法編寫的小問題是,JOIN將被懶惰地執行,每個項目執行一次,並且每次它將從頭構建映射/連接,而它是完全緩存和可重用。在下面的擴展語法中,我只顯式地預先創建一次映射,然後所有其他沒有使用任何實現的惰性查詢共享相同的映射。這樣,它可能是快好幾倍,並使用更少的內存:

var mapping = eList.ToDictionary(x => x.id, x=>x.text); 

var temps = sam.Select(s => 
    new { 
     id = s.id, 
     name = s.name, 
     stringlist = s.list.Select(id => mapping[id]).OrderBy(str => str) 
    }); 

var result = temps.OrderBy(t => t.stringlist.FirstOrDefault()); 
+0

我真正想要實現的是第一個對列表中的「列表」進行排序。那麼之後它會返回'sam'對象中的排序列表。那麼現在'sam'對象會再次排列在我的對象列表中。 – user1120260

+0

如果我很瞭解你,那已經是這樣了。請在我編輯的帖子中查看結果轉儲 – quetzalcoatl

0

試試這個:

var sorted = (from d1 in sam 
       select new 
       { 
        name = d1.name, 
        id = d1.id, 
        list = 
        (
         from d2 in d1.list 
         join e in eList on d2 equals e.id 
         select e.text 
       ) 
       }).OrderBy(item => item.list.OrderBy(i => i).FirstOrDefault());