You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何循环移除List<Location>中4个距指定点最近的元素

需求背景

现有初始化的地点集合如下:

List<Location> locations = new List<Location>();
locations.Add(new Location("Narayana International", 28.6075582, 77.04700729999999));
locations.Add(new Location("Digital zone", 28.8610328484855, 77.0951520020164));
locations.Add(new Location("Vijay computers", 28.841364952771706, 77.09076910484801));
locations.Add(new Location("Codac Info", 29.967759964202948, 76.88406425590289));
locations.Add(new Location("Balaji computers", 30.6920753011206, 76.80162611916126));
locations.Add(new Location("Aadi online exam solutions", 30.393033405609803, 76.79088732285474));

需要实现的逻辑:

  • 计算所有剩余地点与指定坐标的距离,找到距离最近的地点打印到控制台
  • 打印完成后将该地点从集合中移除
  • 重复上述流程,直到累计移除4个元素为止
原代码缺陷
  • 提前一次性计算所有点的距离存入字典,移除元素后字典数据不会同步更新,无法适配多轮查找的需求
  • 固定调用RemoveAt(0)移除索引为0的元素,和「移除当前最近点」的规则完全不符
  • 没有做4次循环的流程控制,只能执行一次查找和固定位置移除操作
  • GetDistance方法里残留了调试用的打印语句,会输出大量无关的中间计算值
实现代码

首先确认Location类结构如下(已有定义可直接跳过):

public class Location
{
    public string Place { get; set; }
    public double Latitude { get; set; }
    public double Longitude { get; set; }

    public Location(string place, double lat, double lng)
    {
        Place = place;
        Latitude = lat;
        Longitude = lng;
    }

    public override string ToString()
    {
        return Place;
    }
}

核心逻辑实现:

// 初始化地点集合
List<Location> locations = new List<Location>();
locations.Add(new Location("Narayana International", 28.6075582, 77.04700729999999));
locations.Add(new Location("Digital zone", 28.8610328484855, 77.0951520020164));
locations.Add(new Location("Vijay computers", 28.841364952771706, 77.09076910484801));
locations.Add(new Location("Codac Info", 29.967759964202948, 76.88406425590289));
locations.Add(new Location("Balaji computers", 30.6920753011206, 76.80162611916126));
locations.Add(new Location("Aadi online exam solutions", 30.393033405609803, 76.79088732285474));

// 指定查询的基准坐标
double searchLat = 19;
double searchLong = 74;
int removeCount = 4; // 需要移除的元素总数

Console.WriteLine($"初始地点总数:{locations.Count}");

// 循环执行4次查找-打印-移除流程
for (int i = 0; i < removeCount; i++)
{
    // 边界判断:剩余地点不足时直接终止
    if (locations.Count == 0) break;

    Location nearest = null;
    double minDistance = double.MaxValue;

    // 遍历当前剩余所有地点,匹配最近点
    foreach (var loc in locations)
    {
        double dist = GetDistance(loc.Latitude, loc.Longitude, searchLat, searchLong);
        if (dist < minDistance)
        {
            minDistance = dist;
            nearest = loc;
        }
    }

    // 打印最近点信息
    Console.WriteLine($"第{i+1}次找到的最近地点:{nearest.Place},距离:{minDistance / 1000:F2}km");
    // 从集合移除该点
    locations.Remove(nearest);
}

Console.WriteLine($"流程结束,剩余地点数量:{locations.Count}");
Console.WriteLine("剩余地点列表:");
foreach (var item in locations)
{
    Console.WriteLine(item.Place);
}
Console.ReadLine();

// 经纬度距离计算方法(Haversine公式,单位:米)
public static double GetDistance(double latitude, double longitude, double otherLatitude, double otherLongitude) 
{
    var d1 = latitude * (Math.PI / 180.0);
    var num1 = longitude * (Math.PI / 180.0);
    var d2 = otherLatitude * (Math.PI / 180.0);
    var num2 = otherLongitude * (Math.PI / 180.0) - num1;
    var d3 = Math.Pow(Math.Sin((d2 - d1) / 2.0), 2.0) + Math.Cos(d1) * Math.Cos(d2) * Math.Pow(Math.Sin(num2 / 2.0), 2.0);
    return 6376500.0 * (2.0 * Math.Atan2(Math.Sqrt(d3), Math.Sqrt(1.0 - d3)));
}
逻辑说明
  • 每一轮查找前都基于当前剩余的集合计算距离,避免提前缓存距离导致的数据不一致问题
  • 遍历过程中直接记录最近的地点对象实例,不需要额外字典存储距离映射,内存占用更低、逻辑更直接
  • 找到最近点后直接调用Remove()方法传入实例对象即可精准移除,不需要依赖索引位置
  • 增加集合为空的边界判断,避免元素不足时抛出空引用异常
  • 距离输出做了单位转换(米转公里),可读性更好

内容的提问来源于stack exchange,提问作者Mahi Patil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 11:12:31