比较三个非常大的大数组并创建一个新对象
Comparing three large very large arrays and creating a new object
好的,所以我在 node.js 中有三个数组,每个数组大约有 65k 个对象。它们都共享一个 ID - PARCELID、SBL 和 SBL20 是相同的。我想将来自不同数组的对象组合成一个对象,然后将其推入最终数组。无论出于何种原因,我得到的输出包含 130k+ 个对象。这也是非常低效的,所以如果有更好的方法来做到这一点,我会洗耳恭听 - 我尝试使用 map() 虽然我只能比较两个数组,而不是三个。我也想加入第四个。
var final = new Array();
count=0
TaxParcels.forEach((TaxParcel) => {
TaxBills.forEach((TaxBill) => {
if (TaxParcel.PARCELID == TaxBill.SBL20) {
CodeEnforcements.forEach((CodeEnforcement) => {
if (TaxParcel.PARCELID == CodeEnforcement.SBL) {
parcel = {
ID: TaxParcel.PARCELID,
DETAILS: {
TaxParcel: TaxParcel,
TaxBill: TaxBill,
CodeEnforcement: CodeEnforcement,
},
};
final.push(parcel);
count++
}
});
}
});
});
console.log(final);
console.log(count)
最简单(也许不是最重要)的方法是避免在此处使用 forEach
:即使在找到元素后,它也会毫无意义地遍历整个数组。没有办法破解forEach
。它可以替换为 for-of
循环和 break
或 find
数组方法。这也将消除重复项。最后一个例子:
const TaxParcels = [{ PARCELID: 1}, { PARCELID: 2}, { PARCELID: 3}];
const TaxBills = [{ SBL20: 1}, { SBL20: 2}, { SBL20: 3}];
const CodeEnforcements = [{ SBL: 1}, { SBL: 2}, { SBL: 3}];
const final = [];
let count=0;
for (const TaxParcel of TaxParcels) {
const ID = TaxParcel.PARCELID;
const TaxBill = TaxBills.find(({ SBL20 }) => SBL20 === ID);
const CodeEnforcement = CodeEnforcements.find(({ SBL }) => SBL === ID);
if (TaxBill && CodeEnforcement) {
count++;
final.push({ ID, DETAILS: { TaxParcel, TaxBill, CodeEnforcement } });
}
}
console.log(count);
console.log(JSON.stringify(final, null, ' '));
但也许最重要的改进是使用更合适的 id-keyed 结构,就像这里的其他答案一样。
您可以通过首先创建一个 Map 来提高性能,该 Map 由键作为键,每个键都有空对象。然后将对象注入到这些对象中,并过滤结果以仅包含具有所有 3 个键的对象:
// sample data
let TaxParcels = [{ PARCELID: 3 }, { PARCELID: 9 }, { PARCELID: 7 }];
let TaxBills = [{ SBL20: 9 }, { SBL20: 1 }, { SBL20: 3 }];
let CodeEnforcements = [{ SBL: 3 }, { SBL: 9 }, { SBL: 1 }];
// Solution
let map = new Map([...TaxParcels, ...TaxBills, ...CodeEnforcements].map(o =>
[o.PARCELID??o.SBL20??o.SBL, {}])
);
for (let o of TaxParcels) map.get(o.PARCELID).TaxParcel = o;
for (let o of TaxBills) map.get(o.SBL20).TaxBill = o;
for (let o of CodeEnforcements) map.get(o.SBL).CodeEnforcement = o;
let result = [...map.values()].filter(o => Object.keys(o).length === 3);
console.log(result);
console.log(result.length);
好的,所以我在 node.js 中有三个数组,每个数组大约有 65k 个对象。它们都共享一个 ID - PARCELID、SBL 和 SBL20 是相同的。我想将来自不同数组的对象组合成一个对象,然后将其推入最终数组。无论出于何种原因,我得到的输出包含 130k+ 个对象。这也是非常低效的,所以如果有更好的方法来做到这一点,我会洗耳恭听 - 我尝试使用 map() 虽然我只能比较两个数组,而不是三个。我也想加入第四个。
var final = new Array();
count=0
TaxParcels.forEach((TaxParcel) => {
TaxBills.forEach((TaxBill) => {
if (TaxParcel.PARCELID == TaxBill.SBL20) {
CodeEnforcements.forEach((CodeEnforcement) => {
if (TaxParcel.PARCELID == CodeEnforcement.SBL) {
parcel = {
ID: TaxParcel.PARCELID,
DETAILS: {
TaxParcel: TaxParcel,
TaxBill: TaxBill,
CodeEnforcement: CodeEnforcement,
},
};
final.push(parcel);
count++
}
});
}
});
});
console.log(final);
console.log(count)
最简单(也许不是最重要)的方法是避免在此处使用 forEach
:即使在找到元素后,它也会毫无意义地遍历整个数组。没有办法破解forEach
。它可以替换为 for-of
循环和 break
或 find
数组方法。这也将消除重复项。最后一个例子:
const TaxParcels = [{ PARCELID: 1}, { PARCELID: 2}, { PARCELID: 3}];
const TaxBills = [{ SBL20: 1}, { SBL20: 2}, { SBL20: 3}];
const CodeEnforcements = [{ SBL: 1}, { SBL: 2}, { SBL: 3}];
const final = [];
let count=0;
for (const TaxParcel of TaxParcels) {
const ID = TaxParcel.PARCELID;
const TaxBill = TaxBills.find(({ SBL20 }) => SBL20 === ID);
const CodeEnforcement = CodeEnforcements.find(({ SBL }) => SBL === ID);
if (TaxBill && CodeEnforcement) {
count++;
final.push({ ID, DETAILS: { TaxParcel, TaxBill, CodeEnforcement } });
}
}
console.log(count);
console.log(JSON.stringify(final, null, ' '));
但也许最重要的改进是使用更合适的 id-keyed 结构,就像这里的其他答案一样。
您可以通过首先创建一个 Map 来提高性能,该 Map 由键作为键,每个键都有空对象。然后将对象注入到这些对象中,并过滤结果以仅包含具有所有 3 个键的对象:
// sample data
let TaxParcels = [{ PARCELID: 3 }, { PARCELID: 9 }, { PARCELID: 7 }];
let TaxBills = [{ SBL20: 9 }, { SBL20: 1 }, { SBL20: 3 }];
let CodeEnforcements = [{ SBL: 3 }, { SBL: 9 }, { SBL: 1 }];
// Solution
let map = new Map([...TaxParcels, ...TaxBills, ...CodeEnforcements].map(o =>
[o.PARCELID??o.SBL20??o.SBL, {}])
);
for (let o of TaxParcels) map.get(o.PARCELID).TaxParcel = o;
for (let o of TaxBills) map.get(o.SBL20).TaxBill = o;
for (let o of CodeEnforcements) map.get(o.SBL).CodeEnforcement = o;
let result = [...map.values()].filter(o => Object.keys(o).length === 3);
console.log(result);
console.log(result.length);