Dart循环对比两列表元素 按经纬度顺序重排嵌套地址列表
Dart 按固定配送路线坐标重排地址列表实现
核心实现思路
直接以有序坐标列表list1为遍历基准,每次从待排序的地址列表list2中匹配经纬度对应的条目,按遍历顺序收集为新列表即可,可严格保证输出顺序和list1完全一致,不会出现排序偏移问题。
基础实现代码
适用于两个列表坐标完全匹配、数据量较小的场景:
void main() { // 固定顺序的配送路线途经点坐标 final list1 = <List<double>>[ [-22.7481495, -43.440236], [-22.7532378, -43.4541717], [-22.9976583, -43.3581268], [-22.8795337, -43.3373482] ]; // 待重排的地址-坐标嵌套列表 final list2 = <List<dynamic>>[ ['SAMPLE ADDRESS A', -22.9976583, -43.3581268], ['SAMPLE ADDRESS B', -22.7481495, -43.440236], ['SAMPLE ADDRESS C', -22.7532378, -43.4541717], ['SAMPLE ADDRESS D', -22.8795337, -43.3373482] ]; final sortedList2 = <List<dynamic>>[]; for (final coord in list1) { final targetLat = coord[0]; final targetLng = coord[1]; // 匹配经纬度对应的地址条目 final matched = list2.firstWhere( (item) => item[1] == targetLat && item[2] == targetLng ); sortedList2.add(matched); } // 验证结果:sortedList2[0] 为 ['SAMPLE ADDRESS B', -22.7481495, -43.440236],符合预期 }
场景适配优化
- 浮点数精度误差适配:如果坐标是经计算得到、存在小数位精度差,不要直接用
==判断,改为差值小于允许阈值的逻辑:
final matched = list2.firstWhere( (item) => (item[1] - targetLat).abs() < 1e-6 && (item[2] - targetLng).abs() < 1e-6 );
- 异常兼容:如果存在坐标缺失、重复的可能,给
firstWhere添加orElse参数做兜底,避免运行时抛出找不到元素的错误。 - 大数据量性能优化:如果列表长度超过1000条,先把
list2转为坐标为键的Map,把查找复杂度从O(n²)降到O(n):
final coordMap = <String, List<dynamic>>{}; for (final item in list2) { // 拼接经纬度作为唯一键,有精度需求可以先截断小数位再拼接 coordMap['${item[1]},${item[2]}'] = item; } final sortedList2 = <List<dynamic>>[]; for (final coord in list1) { final item = coordMap['${coord[0]},${coord[1]}']; if (item != null) sortedList2.add(item); }
内容的提问来源于stack exchange,提问作者João Mário
相关产品推荐
相关产品推荐

