LINQ - 按距离排序(计算值)

时间:2014-07-24 08:12:20

标签: c# linq .net-4.0 xna

我想要的是以距离的升序循环遍历List的每个项目(因此首先使用最近的目标)。

foreach (ShipCompartment enemyComp in enemy.ListOfCompartments.OrderBy(...))

问题是距离不是班级的成员。因此,我无法使用:

foreach (ShipCompartment enemyComp in enemy.ListOfCompartments
    .OrderBy(c => c.Distance))

用于计算距离的代码是:

// Get distance between player and enemy compartments
float distanceToTarget = Vector2.Distance(playerComp.Position,
    enemyComp.Position);

如何将计算结合到OrderBy()中?我查看了here,但它只返回最近的Vector2。

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

简单的选项是将函数调用移到OrderBy调用,如下所示:

foreach (ShipCompartment enemyComp in enemy.ListOfCompartments.OrderBy(c => Vector2.Distance(playerComp.Position, c.Position)))

答案 1 :(得分:1)

如果您需要一般距离(而不仅仅是排序),则最佳解决方案是使用选择创建包含距离定义的新结构,然后使用OrderBy。例如:

对于数据结构:

class Coordinates
{
    public int Value { get; set; }
    public float Longitude { get; set; }
    public float Latitude { get; set; }
}

你这样称呼它:

foreach(var coordinate in coordinates.Select(x=> new 
    {
        Value = x.Value,
        Longitude = x.Longitude,
        Latitude = x.Latitude,
        Distance = x.Longitude + x.Latitude
    }).OrderBy(x=>x.Distance))
    Process(coordinate);

答案 2 :(得分:0)

您还可以创建自己的自定义比较器并将其作为OrderBy参数传递:

public class ShipCompartmentDistanceComparer : IComparer<ShipCompartment>
        {
            public int Compare(ShipCompartmentDistance x,  y)
            {
                float distanceToTargetX = Vector2.Distance(playerComp.Position, x.Position);
                float distanceToTargetY = Vector2.Distance(playerComp.Position, y.Position);
                if (distanceToTargetX > distanceToTargetY)
                    return 1;
                if (distanceToTargetX < distanceToTargetY)
                    return -1;
                else
                    return 0;
            }
        }

然后你只需要打电话:

foreach (ShipCompartment enemyComp in enemy.ListOfCompartments
    .OrderBy(c => c, new ShipCompartmentDistanceComparer()))