我如何在 javascript 中没有嵌套 for 循环的情况下解决这种情况
How can i solve this scenario without nested for loop in javascript
var selectedRows = gridOptions.api.getSelectedRows(); //this is an array
selectedRows.forEach(function(selectedRow, index) {
if (dataSampleAfterUpdate.length == 0) {
dataSampleAfterUpdate.push(selectedRow);
}
for (var x = 0; x < dataSampleAfterUpdate.length; x++) {
if (dataSampleAfterUpdate[x].Id == selectedRow.Id) {
dataSampleAfterUpdate[x] = selectedRow;
} else {
dataSampleAfterUpdate.push(selectedRow);
}
}
});
实际上此代码适用于 10 或 20 条记录。但如果有 500 条记录,页面就会挂起。
有没有使用嵌套 for 循环的替代方法?请帮忙
您有一个 O(n^2)
复杂度算法。您可以在一个对象中跟踪您访问过的项目,而不是数组,因此可以在 O(1)
复杂度中完成查找,并且消除了对内部 for 循环的需要。
据我对您代码的理解,您可能需要以下在 O(n)
时间内运行的简化代码:
var selectedRows = gridOptions.api.getSelectedRows(); //this is an array
var obj = Object.fromEntries(dataSampleAfterUpdate.map(e => [e.Id, e]));
selectedRows.forEach( function(selectedRow, index) {
obj[selectedRow.Id] = selectedRow;
});
dataSampleAfterUpdate = Object.values(obj);
这是对先前答案的改进:
var selectedRows = gridOptions.api.getSelectedRows(); //this is an array
var arr = [...dataSampleAfterUpdate, ...selectedRows];
var obj = Object.fromEntries(arr.map(e => [e.Id, e]));
dataSampleAfterUpdate = Object.values(obj);
这首先将两个数组组合成一个数组arr
。然后通过按 id 对数组进行分组来创建一个对象,以删除重复项。按照设计,它会用下一个遇到的值替换以前的值。
要更好地理解这一点,您可以扩展 运行 下面的代码片段。解释了各个步骤。
var dataSampleAfterUpdate = [{Id: 1, Data: "a"}, {Id: 2, Data: "b"}, {Id: 3, Data: "c"}];
var selectedRows = [{Id: 2, Data: "bb"}, {Id: 4, Data: "dd"}];
// Combine the arrays into a nested array with eventual key value pairs (key = id).
var arr = [...dataSampleAfterUpdate, ...selectedRows];
console.log("Log 1:", JSON.stringify(arr));
// Converts into a nested array with eventual key value pairs (key = id).
var temp = arr.map(e => [e.Id, e]);
console.log("Log 2:", JSON.stringify(temp));
// Converts key value pair to object. Removes duplicate ids. By design object can only hold one value per key.
var obj = Object.fromEntries(temp);
console.log("Log 3:", JSON.stringify(obj));
// Converts back to array of values.
dataSampleAfterUpdate = Object.values(obj);
console.log("Log 4:", JSON.stringify(dataSampleAfterUpdate));
var selectedRows = gridOptions.api.getSelectedRows(); //this is an array
selectedRows.forEach(function(selectedRow, index) {
if (dataSampleAfterUpdate.length == 0) {
dataSampleAfterUpdate.push(selectedRow);
}
for (var x = 0; x < dataSampleAfterUpdate.length; x++) {
if (dataSampleAfterUpdate[x].Id == selectedRow.Id) {
dataSampleAfterUpdate[x] = selectedRow;
} else {
dataSampleAfterUpdate.push(selectedRow);
}
}
});
实际上此代码适用于 10 或 20 条记录。但如果有 500 条记录,页面就会挂起。 有没有使用嵌套 for 循环的替代方法?请帮忙
您有一个 O(n^2)
复杂度算法。您可以在一个对象中跟踪您访问过的项目,而不是数组,因此可以在 O(1)
复杂度中完成查找,并且消除了对内部 for 循环的需要。
据我对您代码的理解,您可能需要以下在 O(n)
时间内运行的简化代码:
var selectedRows = gridOptions.api.getSelectedRows(); //this is an array
var obj = Object.fromEntries(dataSampleAfterUpdate.map(e => [e.Id, e]));
selectedRows.forEach( function(selectedRow, index) {
obj[selectedRow.Id] = selectedRow;
});
dataSampleAfterUpdate = Object.values(obj);
这是对先前答案的改进:
var selectedRows = gridOptions.api.getSelectedRows(); //this is an array
var arr = [...dataSampleAfterUpdate, ...selectedRows];
var obj = Object.fromEntries(arr.map(e => [e.Id, e]));
dataSampleAfterUpdate = Object.values(obj);
这首先将两个数组组合成一个数组arr
。然后通过按 id 对数组进行分组来创建一个对象,以删除重复项。按照设计,它会用下一个遇到的值替换以前的值。
要更好地理解这一点,您可以扩展 运行 下面的代码片段。解释了各个步骤。
var dataSampleAfterUpdate = [{Id: 1, Data: "a"}, {Id: 2, Data: "b"}, {Id: 3, Data: "c"}];
var selectedRows = [{Id: 2, Data: "bb"}, {Id: 4, Data: "dd"}];
// Combine the arrays into a nested array with eventual key value pairs (key = id).
var arr = [...dataSampleAfterUpdate, ...selectedRows];
console.log("Log 1:", JSON.stringify(arr));
// Converts into a nested array with eventual key value pairs (key = id).
var temp = arr.map(e => [e.Id, e]);
console.log("Log 2:", JSON.stringify(temp));
// Converts key value pair to object. Removes duplicate ids. By design object can only hold one value per key.
var obj = Object.fromEntries(temp);
console.log("Log 3:", JSON.stringify(obj));
// Converts back to array of values.
dataSampleAfterUpdate = Object.values(obj);
console.log("Log 4:", JSON.stringify(dataSampleAfterUpdate));