目前,我正在使用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();我想把它转换成一个内部排序,我想使用List<T>.Sort()方法。但是,如果我只按一件事排序,我就知道如何做到这一点,因为我是通过PossibleMoveLocationOrdering (返回一个int),然后由计算为int的IsSameType(PML) ? (_Owner[PML] as TileFlowing).UnitsWithin : 0,然后由Randomiser.Next() (返回一个随机的int)来排序的,我不知道如何做到这一点。
问题:如何编写比较函数(或者是否有更好的方法)来执行上面的LINQ查询。
发布于 2011-06-13 09:28:41
首先,指定三个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();就我个人而言,我只需要用点符号来表示:
var query = PossibleMoveLocations
.OrderBy(pml => PossibleMoveLocationOrdering(PML))
.ThenBy(pml => IsSameType(pml) ?
(_Owner[pml] as TileFlowing).UnitsWithin : 0)
.ThenBy(pml => Randomiser.Next())
.ToList();要进行排序,基本上需要一个可以测试多个事物的Comparison<T>或IComparer<T>,还需要一个使用属性创建比较器的实现。您可以手动这样做(按照Marc的代码),但碰巧的是,我在MiscUtil中有一些助手类和扩展方法
var comparer = ProjectionComparer<PossibleMove>
.Create(pml => PossibleMoveLocationOrdering(PML));
.ThenBy(pml => IsSameType(pml) ? ...)
.ThenBy(...);
list.Sort(comparer);请注意,在这里使用Randomizer绝对不是一个好主意,因为它将在每个比较中被调用(对于第一部分相同的对象).这可能导致不一致的比较,例如x < y < z < x。
发布于 2011-06-13 09:24:24
最常见的是:
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;
});或者类似的(可能在比较类中,如果它是非平凡的)。
https://stackoverflow.com/questions/6328612
复制相似问题