2012-09-05 32 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());