示例输入和当前输出,不进行排序:
List<List<string>> _optoGrid = new List<List<string>>();
_optoGrid.Add(new List<string>() {"10", "10", "100", "20", "10", "10"});
_optoGrid.Add(new List<string>() {"20", "20", "50", "10", "1546", "555"});
_optoGrid.Add(new List<string>() {"30", "30", "10", "10", "10", "100"});
_optoGrid.Add(new List<string>() {"30", "30", "10", "1", "10", "100"});
显示这是排序代码的位置。
foreach (List<string> list in _optoGrid)
{
foreach (string s in list)
{
Console.Write(s + ", ");
}
Console.WriteLine();
}
当前输出:
10,10,100,20,10,10,
20,20,50,10,1546,555,
30,30,10,10,10,100,
30,30,10,1,10,100,
期望的输出假定按第5列排序(从0开始):
20,20,50,10,1546,555,
30,30,10,10,10,100,
30,30,10,1,10,100,
10,10,100,20,10,10,
我想输入:
_optogrid.Sort(5) //5 being the 'column' number
答案 0 :(得分:4)
此代码没有列,它是一个包含列表的列表。 LINQ仍然可以订购结果。在LINQ中对结果进行排序的方法是OrderBy()
和OrderByDescending()
。它的参数是一个lambda,它产生排序键。
在这种情况下,lambda应该返回应该用于订购的列表项,例如:
var _optoGrid = new List<List<string>>{
new List<string> {"10", "10", "100", "20", "10", "10"},
new List<string> {"20", "20", "50", "10", "1546", "555"},
new List<string> {"30", "30", "10", "10", "10", "100"},
new List<string> {"30", "30", "10", "1", "10", "100"}
};
var orderedResults=_optoGrid.OrderBy(lst=>lst[5]);
或
var orderedResults=_optoGrid.OrderByDescending(lst=>lst[5]);
那是非常脆弱的代码。不能保证所有列表具有相同数量的项目。忘记一个值或再输入一个值很容易。如果一个列表包含少于6个项目,则.OrderBy(lst=>lst[5])
将抛出该错误,但是如果使用了错误个项目,则不会抱怨。
最好使用适当的类而不是列表,尤其是在所有项目都具有相同数量的项目的情况下,例如:
class MyItem
{
public string ProperlyNamedProperty1{get;set;}
...
public MyItem(string prop1,string prop2,...)
{
ProperlyNamedProperty1=prop1;
...
}
}
var _optoGrid = new List<MyItem>{
new MyItem("10", "10", "100", "20", "10", "10"),
};
var orderedResults=_optoGrid.OrderBy(item=>item.Property6);
如果列表仅在本地使用(例如,以一种方法),则也可以使用值元组。当然,6个属性太多了:
var _optoGrid = new List<(string prop1, string prop2, string prop3, string prop4, string prop5, string prop6)>{
("10", "10", "100", "20", "10", "10"),
("20", "20", "50", "10", "1546", "555"),
("30", "30", "10", "10", "10", "100"),
("30", "30", "10", "1", "10", "100")
};
var orderedResults=_optoGrid.OrderBy(tuple=>tuple.prop6);
如果一个人觉得很懒惰,并且物品的数量不是那么多,则可以省略名称:
var _optoGrid = new List<(string, string, string, string, string, string)>{
("10", "10", "100", "20", "10", "10"),
("20", "20", "50", "10", "1546", "555"),
("30", "30", "10", "10", "10", "100"),
("30", "30", "10", "1", "10", "100")
};
var orderedResults=_optoGrid.OrderBy(tuple=>tuple.Item6);
元组的好处是它们是强类型的。没有理由对所有它们都使用相同的类型,例如:
var _optoGrid = new List<(int, int, string, string, string, double)>{
(10, 10, "100", "20", "10", 10),
(20, 20, "50", "10", "1546", 555),
(30, 30, "10", "10", "10", 100),
(30, 30, "10", "1", "10", 100)
};
var orderedResults=_optoGrid.OrderBy(tuple=>tuple.Item6);
这避免了另一个棘手的问题,即字典顺序问题。如果我将字符串从"10"
更改为"1000" it will *still* appear before "555", because words that start with
“ 1” always come before words that start with
“ 5”。使用字符串,OrderBy
将返回:
10 10 100 20 10 10000
20 20 50 10 1546 555
糟糕。
尽管在第六个字段中使用int
或double
,我们得到了预期的顺序:
20 20 50 10 1546 555
10 10 100 20 10 10000
答案 1 :(得分:1)
每个列表至少包含6个元素,并且项必须按字母顺序(而不是数字)排序:
IEnumerable<List<string>> sortedLists = _optoGrid.OrderByDescending(l => l[5]);
foreach (List<string> l in sortedLists)
{
Console.WriteLine(string.Join(", ", l);
}
答案 2 :(得分:0)
这看起来像是按特定列号对表格进行排序。
Enumerable.OrderBy
将完成这项工作。
Enumerable.OrderBy,它包含一系列TRow
个项目和一个keySelector。 keySelector是一个函数,它以TRow
作为输入并返回一个必须对序列进行排序的值。
在您的情况下,TRow
是List<string>
。因此,如果您需要按索引为sortColumnIndex
的列进行排序,则需要一个带有List<String> row
并返回row[sortColumnIndex]
如何?
int sortColumnIndex = 5; //按第5列排序 列表> unorderedList = ... 清单orderedList = unorderedList.OrderBy(row => row [sortColumnIndex]);
简单的漫画卓悦!