Geo*_*ett 5 c# linq sorting list
目前,我正在使用LINQ对象对列表进行排序,然后ToList()对结果进行处理:
var SortedPossibleMoveLocations = (from PML in PossibleMoveLocations
orderby Randomiser.Next()
orderby IsSameType(PML) ? (_Owner[PML] as TileFlowing).UnitsWithin : 0
orderby PossibleMoveLocationOrdering(PML)
select PML).ToList();
Run Code Online (Sandbox Code Playgroud)
我想转换它来做一个inplace sort,我想使用List<T>.Sort()方法.如果我只是按一个事情排序,我知道如何做到这一点,但是,因为我按顺序排序PossibleMoveLocationOrdering(返回一个int)然后通过IsSameType(PML) ? (_Owner[PML] as TileFlowing).UnitsWithin : 0哪个计算结果为a int,然后通过Randomiser.Next()(返回一个随机int)我不这样做知道怎么做.
问题:如何编写比较函数(或者有更好的方法)来执行上面的LINQ查询.
Jon*_*eet 11
首先,指定三个orderby子句是个坏主意 - 而是仅使用逗号分隔指定多个排序.
我也不热衷于使用Randomiser.Next()订购的想法,但这是一个不谈.
您的LINQ查询应该如下所示(目前仍在使用Randomiser中):
var query = (from PML in PossibleMoveLocations
orderby PossibleMoveLocationOrdering(PML),
IsSameType(PML) ? (_Owner[PML] as TileFlowing).UnitsWithin : 0,
Randomiser.Next()
select PML).ToList();
Run Code Online (Sandbox Code Playgroud)
就个人而言,我只是使用点符号:
var query = PossibleMoveLocations
.OrderBy(pml => PossibleMoveLocationOrdering(PML))
.ThenBy(pml => IsSameType(pml) ?
(_Owner[pml] as TileFlowing).UnitsWithin : 0)
.ThenBy(pml => Randomiser.Next())
.ToList();
Run Code Online (Sandbox Code Playgroud)
要进行排序,您基本上需要一个Comparison<T>或IComparer<T>哪个可以测试多个东西,还有一个使用属性创建比较器的实现.你可以手动完成(按照Marc的代码),但是当它发生时,我在MiscUtil中有一些帮助类和扩展方法:
var comparer = ProjectionComparer<PossibleMove>
.Create(pml => PossibleMoveLocationOrdering(PML));
.ThenBy(pml => IsSameType(pml) ? ...)
.ThenBy(...);
list.Sort(comparer);
Run Code Online (Sandbox Code Playgroud)
请注意,使用Randomizer这里绝对是一个坏主意,因为它会在每个比较(与相等的第一件物品)被称作......这可能会导致不一致的比较,从而x< y< z< x.
最常见的:
list.Sort((x,y) => {
int result = /* first comparison, for example
string.Compare(x.Name, y.Name) */
if (result == 0) result = /* second comparison,
for example x.Id.CompareTo(y.Id) */
...
if (result == 0) result = /* final comparison */
return result;
});
Run Code Online (Sandbox Code Playgroud)
或类似的(可能在比较者类中,如果它是非平凡的).