在我的c#MVC项目中,我有一个项目列表,我想按照另一个列表的顺序排序
var FruitTypes = new List<Fruit> {
new Fruit { Id = 1, Name = "Banana"},
new Fruit { Id = 2, Name = "Apple" },
new Fruit { Id = 3, Name = "Orange" },
new Fruit { Id = 4, Name = "Plum"},
new Fruit { Id = 5, Name = "Pear" },
};
SortValues = new List<int> {5,4,3,1,2};
目前我的列表显示为水果类型的默认值。
如何按SortValues对Fruit列表进行排序?
答案 0 :(得分:9)
目前还不清楚您是按SortValues
中的索引排序,还是SortValues
包含应加入的相应Id
值。
在第一种情况下:
首先,你必须将https://codepen.io/panchroma/pen/VXOZVW两个列表放在一起,然后你可以对Zip生成的复合类型进行排序,然后选择退出的FruitType。
IEnumerable<FruitType> sortedFruitTypes = FruitTypes
.Zip(SortValues, (ft, idx) => new {ft, idx})
.OrderBy(x => x.idx)
.Select(x => x.ft);
但是,这只是按照SortValues
中指示的顺序对第一个列表进行排序, 不 加入ID。
在第二种情况下,简单的连接就足够了:
IEnumerable<FruitType> sortedFruitTypes = SortValues
.Join(FruitTypes, sv => sv, ft => ft.Id, (_, ft) => ft);
这是有效的,因为Enumerable.Join
维持了&#34; left&#34;的顺序。手边加入。
答案 1 :(得分:1)
虽然几乎可以肯定有更多的LINQ-y方式,但如果你倾向于冗长,你可以使用迭代器函数来实现这一点。例如:
public IEnumerable<Fruit> SortFruits(IEnumerable<Fruit> unordered, IEnumerable<int> sortValues)
{
foreach (var value in sortValues)
yield return unordered.Single(f => f.Id == value);
}
我喜欢它明确表达自己的所作所为。当每个列表中的项目数不同时,您可以考虑抛出异常,或者如果没有排序值,您可能只是不返回项目。你必须决定应该采取什么样的行为&#34;缺少&#34;两个集合中的值都是。我认为必须处理这些场景是一个很好的理由将它全部放在一个方法中,而不是更长的LINQ查询。
答案 2 :(得分:0)
时间复杂度:Linq的O(n)+ TM
使用Linq FirstOrDefault 按排序值获取元素。
List<int> SortValues = new List<int> { 5, 4, 3, 1, 2 };
List<Fruit> result = new List<Fruit>();
foreach (var element in SortValues)
{
Fruit f = FruitTypes.FirstOrDefault(fruitElement => fruitElement.Id == element);
result.Add(f);
}