是否可以对一种类型的集合执行 LINQ 聚合到不同的结果类型



我想在(纬度、经度(对的集合上使用单个 LINQ 聚合并生成两个(纬度、经度(对:

public Location {
   public double Latitude;
   public double Longitude;
}
List<Location> border = ...;

我可以通过以下方法轻松获得最小(纬度、经度(对:

var minBorder =  border.Aggregate( new Location()
                                 { Latitude = double.MaxValue, Longitude = double.MaxValue },
                                 (current, next) =>
                                   new Location()
                                   {
                                     Latitude = (next.Latitude < current.Latitude) ? next.Latitude : current.Latitude,
                                     Longitude = (next.Longitude < current.Longitude) ? next.Longitude : current.Longitude
                                   }) ;

如果可能的话,我想使用单个聚合返回两个位置;最小(纬度,经度(对和最大(纬度,经度(对而不是一个。

如果我为结果声明一个类:

public class BorderBounds {
   public double MinLatitude;
   public double MinLongitude;
   public double MaxLatitude;
   public double MaxLongitude;
}

并修改聚合:

var borderBounds =  border.Aggregate( new Location()
                                 { Latitude = double.MaxValue, Longitude = double.MaxValue },
                                 (current, next) =>
                                   new BorderBounds()
                                   {
                                    ...
                                   }) ;

假定(current, next)参数的类型为 BorderBounds 而不是 Location

有没有办法构建这样的聚合?最好简单地将其转换为foreach吗?

你可以做到。我建议使边界可变,或者创建一个可变的边界构建器,之后可以创建一个边界对象,只是为了节省不必要的内存分配:

locations.Aggregate(new Bounds(), (bounds, location) =>
        {
            if (bounds.MinLat > location.Latitude) bounds.MinLat = location.Latitude;
            if (bounds.MaxLat < location.Latitude) bounds.MaxLat = location.Latitude;
            if (bounds.MinLon > location.Longitude) bounds.MinLon = location.Longitude;
            if (bounds.MaxLon < location.Longitude) bounds.MaxLon = location.Longitude;
            return bounds;
        });

和类

internal class Location
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}
internal class Bounds
{
    public Bounds()
    {
        MinLat = double.MaxValue;
        MaxLat = double.MinValue;
        MinLon = double.MaxValue;
        MaxLon = double.MinValue;
    }
    public double MinLat { get; set; }
    public double MaxLat { get; set; }
    public double MinLon { get; set; }
    public double MaxLon { get; set; }
}
border
    .Aggregate(new BorderBounds() 
             { MinLatitude = double.MaxValue, 
               MinLongitude = double.MaxValue, 
               MaxLongitude = double.MinValue, 
               MaxLatitude = double.MinValue }, 
               (current, next) => new BorderBounds {
                   MinLatitude = next.Latitude < current.MinLatitude ? next.Latitude : current.MinLatitude,
                   MinLongitude = next.Longitude < current.MinLongitude ? next.Longitude : current.MinLongitude,
                   MaxLatitude = next.Latitude > current.MaxLatitude ? next.Latitude : current.MaxLatitude,
                   MaxLongitude = next.Longitude > current.MaxLongitude ? next.Longitude : current.MaxLongitude
                } 
     ); 
聚合函数的返回类型

与传入的种子相同,而不是集合本身的返回类型。

我假设你在这里构建了一个边界框之类的东西。

var borderBounds = border.Aggregate(new BorderBounds 
{
    MinLatitude = double.MaxValue,
    MinLongitude = double.MaxValue,
    MaxLatitude = double.MinValue,
    MaxLongitude = double.MinValue
}, 
(current, next) => new BorderBounds
{
    MinLatitude = Math.Min(current.MinLatitude, next.Latitude),
    MinLongitude = Math.Min(current.MinLongitude, next.Longitude),
    MaxLatitude = Math.Max(current.MaxLatitude, next.Latitude),
    MaxLongitude = Math.Max(current.MaxLongitude, next.Longitude),
});

最新更新