我有两个机场数据集 - 一个存储在本地,另一个从服务器获取。
本地数据集airports
有大约 45,000 个单独的对象,其中每个对象具有以下结构:
{
"ident": "AYPY",
"type": "large_airport",
"name": "Port Moresby Jacksons International Airport",
"latitude_deg": -9.443380356,
"longitude_deg": 147.2200012,
"iso_country": "PG"
},
获取的数据集是使用createDestinationObject(title)
创建的,该从title
页面获取相关数据并将其存储在finalList
变量中。这是它的外观:
{
"ICAO": "AYPY",
"name": "Port Moresby Jacksons International Airport",
"latitude": 0,
"longitude": 0,
},
获取的数据集缺少坐标(因此占位符为零)。我想通过将airports.ident
与finalList.ICAO
匹配来获取airports
数据集中的坐标,因为它们都是机场的标准国际民航组织代码。然后,我将airports
匹配项中的latitude_deg
和longitude_deg
值分配给finalList
项的latitude
和longitude
属性。
为了尝试解决这个问题,我使用了一个嵌套的 for 循环,其中每个finalList
项都循环遍历airports
数据集,如果 ICAO 代码匹配,它将分配坐标。代码有效,但问题是它需要相当长的时间(如果数据集有>300 个对象finalList
甚至长达 20-30 秒)。有没有办法更快地解决这个问题,而无需通过airports
数据集中的每个 +40k 项循环每个finalList
项?
import airports from './airports.json';
async function assignCoordinates(title) {
var finalList = await createDestinationObject(title);
for (var destination in finalList) {
for (var airport in airports) {
if (finalList[destination].ICAO === airports[airport].ident) {
finalList[destination].latitude = airports[airport].latitude_deg;
finalList[destination].longitude = airports[airport].longitude_deg;
}
}
}
console.log(finalList);
}
var title = "Vilnius_Airport";
assignCoordinates(title);
我对Javascript非常陌生,所以我的代码总体上可能很草率,不要犹豫批评。
编辑:
为了提供更多信息,airports
存储在本地并导入到.js文件中。
finalList
是从title
机场出发的目的地(机场)列表。createDestinationObject(title)
功能:
- 从
title
页面获取维基百科部分列表。 - 查找列出目标的部分。
- 从此部分获取维基文本并将其字符串化。
- 过滤文本以查找令人垂涎的机场及其页面名称。
- 获取每个机场的摘要,并使用正则表达式在摘要或信息框中查找 ICAO 代码。
- 返回一个嵌套对象,其中
finalList.ICAO
是获取的 ICAO 代码;finalList.name
是目的地部分维基文本中的机场名称;finalList.longitude
和finalList.latitude
是用于存储坐标数据的占位符属性。finalList
中的对象数量与title
机场的目的地数量一样多,每个对象都是一个目的地机场。
createDestinationObject(title)
函数本身可能需要 1-2 秒才能运行。
为了提高一次又一次访问每个目的地的机场数组的复杂性,您可以先花费整个访问其元素的时间,只是为了创建一个将每个.ident
值绑定到相应机场对象的地图。
获得该地图后,您可以执行算法,对于从 api fetch 返回的数组中的每个目的地,它只需执行airportsMap[destination.ICAO]
来选择相应的机场,如果找到,则相应地设置其纬度和经度。
我用来制作这种地图的策略是:
let airportsMap = Object.assign({}, ...airports.map((a) => ({[a.ident]: a})));
这只是将来自airports.map
的所有属性(键值对)分配给空对象
var airports = [
{
"ident": "AYPY",
"type": "large_airport",
"name": "Port Moresby Jacksons International Airport",
"latitude_deg": -9.443380356,
"longitude_deg": 147.2200012,
"iso_country": "PG"
},
{
"ident": "ZHHE",
"type": "large_airport",
"name": "Another International Airport",
"latitude_deg": -65.3422234,
"longitude_deg": 143.653453,
"iso_country": "US"
},
];
const createDestinationObject = (title) => {
return [{
"ICAO": "AYPY",
"name": "Port Moresby Jacksons International Airport",
"latitude": 0,
"longitude": 0,
},
{
"ICAO": "notexisting",
"name": "...",
"latitude": 0,
"longitude": 0,
},
];
};
//this will create a map where each airport is indexed by ICAO
let airportsMap = Object.assign({}, ...airports.map((a) => ({[a.ident]: a})));
function assignCoordinates(title) {
var finalList = createDestinationObject(title);
for (let destination of finalList) {
if (Object.hasOwn(airportsMap, destination.ICAO)) {
const airport = airportsMap[destination.ICAO];
destination.latitude = airport.latitude_deg;
destination.longitude = airport.longitude_deg;
}
}
return finalList;
}
var title = "bogus";
const o = assignCoordinates(title);
console.log(o);