从与 JSON 对象数组匹配的巨大 JSON 对象数组获取索引的最佳方法是什么

What is the best way of getting index from huge JSON Array of objects that matches with array of JSON objects

我想知道从巨大的(数组长度接近 150 000)JSON 与 JSON 对象数组匹配的 JSON 对象数组中获取索引的最佳方法。

目前我正在使用 for 循环来完成这项工作,但它需要 3 到 4 分钟的时间。有什么最好的方法可以提高性能吗?下面是一个说明我的要求的例子。

var hugeArray = [
    {firstName:"John", lastName:"Doe", age:21},
    {firstName:"Abraham", lastName:"Lincoln", age:46},
    {firstName:"Andy", lastName:"Crossland", age:32},
    .
    .
    .
    {firstName:"Jimmy", lastName:"Fletcher", age:65}
];

假设 hugeArray 的长度为 150 000。我有另一个 JSON 长度为 15 000 的数组(matchArray)。

var matchArray = [
    {firstName:"John", lastName:"Doe"},
    {firstName:"Andy", lastName:"Crossland"},
    .
    .
    .
    {firstName:"Jimmy", lastName:"Fletcher"}
];

我想要 hugeArray 中与 matchArray 匹配的索引。

例如从上面的数据,matchArray有对象列表,这些对象要和hugeArray中的对象进行匹配。如果匹配则 hugeArray 的 return 个索引。以上示例的输出如下所示。

[0,2,...,150000]

为此,我编写了一个函数,该函数 returns hugeArray 的索引。如果 matchArray 对象与 hugeArray 匹配,则 return 匹配的 hugeArray 的索引否则 returns -1.

//returns -1 if no matched objects found otherwise returns index of searchArray that matched with obj.
//searchArray : Array that used to search in and return matched index.
//obj : JSON object which is used to match in with searchArray objects.
function getArrayIndex(searchArray,obj){
    var index = -1;
    for(var i=0,searchArrayLen=searchArray.length;i<searchArrayLen;i++){
        var keyMatch = true;
        for(var key in obj){
            if(obj[key].trim() !== searchArray[i][key].trim()){
                keyMatch = false;
                break;
            }
        }
        if(keyMatch){
            index = i;
            return index;
        }
    }
    return index;
}

写在getIndexes函数下面调用上面的getArrayIndex函数。

//returns array of indexes.
function getIndexes(hugeArray,matchArray){
    var indexArray = [];
    var matchArrayLen = matchArray.length;
    for(var i=0; i<matchArrayLen; i++){
        var matchIndex = getArrayIndex(hugeArray,matchArray[i]);
        if(matchIndex !== -1){
            indexArray.push(matchIndex);
        }
    }
    return indexArray;
}

最后通过调用getIndexes函数,以数组形式给出所有匹配的索引。

例如,

var index = getIndexes(hugeArray,matchArray);
console.log(index);// This prints an array that contains matched indexes.
//For above data, output will be like [0,2,...,150000].

您可以为此使用 Map Object

let theMap = new Map(hugeArray.map((item, index) => [item.firstName + " " + item.lastName, index]));

let result = matchArray.map(item => theMap.get(item.firstName + " " + item.lastName))
  .filter(i => i !== undefined)

这假设 firstNamelastName 没有空格。如果它们可能包含空格,请使用另一个字符。

如果 hugeArray 有重复:

let theMap = new Map();
hugeArray.forEach((item, index) => {
  let key = item.firstName + " " + item.lastName;
  let value = theMap.get(key);
  if (value === undefined)
    theMap.set(key, [index]);
  else
    value.push(index);
});

let result = matchArray.flatMap(item => theMap.get(item.firstName + " " + item.lastName))
  .filter(i => i !== undefined);

如果在 hugeArray 有重复项时需要排序结果:

let result = matchArray.flatMap(item => theMap.get(item.firstName + " " + item.lastName))
      .filter(i => i !== undefined).sort();