【问题标题】:Sorting IEnumerable in LINQ [duplicate]在LINQ中对IEnumerable进行排序[重复]
【发布时间】:2012-09-05 07:27:13
【问题描述】:

可能重复:
Sorting an IEnumerable in LINQ

是否可以不使用 .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());

【问题讨论】:

  • 顺便说一句,您的命名约定很痛苦。
  • 这只是一种练习......命名不是我关心的......谢谢
  • 老实说,这一次我认为你想要ToList。否则,您的list 成员包含IEnumerable,而不是List,并且每次您枚举它时,它都会重新执行连接。如果您不介意这一点,您可以直接删除 ToList 调用,顺序仍然相同。
  • @Rawling,对不起,但它不起作用..它根本不对列表进行排序。

标签: c# linq sorting ienumerable


【解决方案1】:

也许 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() 来防止每次访问集合时进行排序。

【讨论】:

  • 它不起作用......'string'不包含'list'的定义,并且没有扩展方法'list'接受'string'类型的第一个参数...... .
  • 哦,对了。我刚刚编辑。试试新的。
  • ) 预期...将其添加到 OrderBy() 中但出现错误...“System.Collections.Generic.IEnumerable”不包含“ThenBy”的定义并且没有扩展方法 'ThenBy' 接受类型为 'System.Collections.Generic.IEnumerable' 的第一个参数
  • 是的,ThenBy 在这里没有意义,因为排序的是内部枚举,而不是外部枚举。
  • 等等,删除 ToList() 有什么问题。它对我来说很好。
【解决方案2】:

我刚刚测试了没有“ToList”的原始代码,它对项目和“附加”进行了很好的排序。你能详细说明你想要实现的目标吗?证明:

使用 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());

【讨论】:

  • 我真正想要实现的是第一个对列表中的“列表”进行排序。然后,它将返回“sam”对象中的排序列表。那么现在'sam'对象将再次排序到我的对象列表中。
  • 如果我理解你的话,它已经像那样工作了。请在我编辑的帖子中查看结果转储
【解决方案3】:

试试这个:

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());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 2011-04-07
    相关资源
    最近更新 更多