2012-01-27 44 views
14

嵌套列表我有一个嵌套列表,排序依据/ ThenBy循环 - 在C#

List<List<String>> intable; 

,我想所有的列进行排序。问题是列数取决于用户输入。

列表进行排序,这样工作正常(假设4列本示例)

var tmp = intable.OrderBy(x => x[0]); 
tmp = tmp.ThenBy(x => x[1]); 
tmp = tmp.ThenBy(x => x[2]); 
tmp = tmp.ThenBy(x => x[3]); 
intable = tmp.ToList(); 

但是,当我把它放在一个循环,这样的:

var tmp = intable.OrderBy(x => x[0]); 
for (int i = 1; i <= 3; i++) 
{ 
     tmp = tmp.ThenBy(x => x[i]); 
} 
intable = tmp.ToList(); 

它不再作品正确,并只排序第四列。

+1

看到这个[http://social.msdn.microsoft .COM /论坛/ EN-US/linqprojectgeneral /线程/ 61e502b4-6795-4e51-b70e-2be642cfc413 /(http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/61e502b4-6795 -4e51-b70e-2be642cfc413 /) – 2012-01-27 18:22:55

回答

24

这是一个的情况下访问修改的封闭。修改代码,这和它的工作:

var tmp = intable.OrderBy(x => x[0]); 
for (int i = 1; i <= 3; i++) { 
    var thisI = i; 
    tmp = tmp.ThenBy(x => x[thisI]); 
} 
intable = tmp.ToList(); 

埃里克利珀写了two-part article描述问题。之所以不能如你所期望的那样工作,简而言之,是因为当您拨打ToList()时,LINQ仅使用最后一个值i进行评估。这是一样的,如果你这样写:

var tmp = intable.OrderBy(x => x[0]); 
tmp = tmp.ThenBy(x => x[3]); 
tmp = tmp.ThenBy(x => x[3]); 
tmp = tmp.ThenBy(x => x[3]); 
intable = tmp.ToList(); 
+5

Eric Lippert确认封闭行为将改变在C#5. [SO链接这里](http://stackoverflow.com/a/8899347/498969) – 2012-01-27 18:26:11

+6

@AdamSpicer:它不会改变为“for”循环,只为“foreach”循环。 – 2012-01-29 16:58:43

+0

@EricLippert,感谢您的澄清! – 2012-01-29 21:55:41

0

创建一个比较器

class StringListComparer : IComparer<List<string>> 
{ 
    public int Compare(List<string> x, List<string> y) 
    { 
     int minLength = Math.Min(x.Count, y.Count); 
     for (int i = 0; i < minLength; i++) { 
      int comp = x[i].CompareTo(y[i]); 
      if (comp != 0) { 
       return comp; 
      } 
     } 
     return x.Count.CompareTo(y.Count); 
    } 
} 

然后将列表排序这样

intable.Sort(new StringListComparer());