I have a nested list,
List<List<String>> intable;
where I would like to sort all the columns. The problem is that the number of columns depends on user input.
Sorting the list like this works fine (assuming 4 columns for this example)
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();
But, when I put it in a loop, like this:
var tmp = intable.OrderBy(x => x[0]);
for (int i = 1; i <= 3; i++)
{
tmp = tmp.ThenBy(x => x[i]);
}
intable = tmp.ToList();
it no longer works correctly, and sorts only the fourth column.
This is a case of access to a modified closure. Change the code to this and it will work:
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();
Eric Lippert has written a two-part article describing the problem. The reason it doesn't work as you expect to is - in short - because LINQ is only using the last value of i
when it is evaluated when you call ToList()
. It's the same as if you had written:
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With