簡體   English   中英

從 JavaScript 中的對象數組中刪除的有效方法

[英]Efficient way to delete from an array of objects in JavaScript

frontendtasks = [
                 {"id": 1, "name": "User Deletion", "script": "UserDeletion"},
                 {"id": 2, "name": "User Creation", "script_name": "UserCreation"}
                ]

backendtasks = [
                {"id": 1, "name": "User Deletion", "script": "UserDeletion_V2"}
               ]

我正在嘗試刪除 frontendtask 中 id = 1 的條目,並使用此代碼從 backendtask 中推送該條目。

if (backendtasks != 0) {
    for (updated_task in backendtasks ) {
        for (oldtask in frontendtasks) {
            if (frontendtasks[oldtask].id == backendtasks[updated_task].id) {
                frontendtasks[oldtask] = backendtasks[updated_task]
                delete backendtasks[updated_task];
                break;
            }
        }
    }
    for (new_task in backendtasks) {
        frontendtasks.unshift(backendtasks[new_task])
    }
}

這真的很慢,CPU 在瀏覽器中達到 100%,有 700 個項目。 有沒有有效的方法來實現這個?

不要遍歷兩個 arrays,而是使用 object 到 map 后端 ID 值:

const mappings = {};
for (const task of backendtasks) {
    mappings[task.id] = task;
}
for (let i = 0; i < frontendtasks.length; i ++) {
    const curid = frontendtasks[i].id;
    if (curid in mappings) {
        frontendtasks[i] = mappings[curid];
        delete mappings[curid];
    }
}
// push is faster than unshift
for (const key in mappings) {
    frontendtasks.push(mappings[key]);
}

方法:由於您有 2 個 arrays,我建議首先將后端數組規范化為 object,然后迭代前端數組並在規范化的 object 中查找,因為與數組中的 O(n) 相比,object 中的查找為 O(1)。

 function getFrontendTasks(){ const frontendtasks = [ {"id": 1, "name": "User Deletion", "script": "UserDeletion"}, {"id": 2, "name": "User Creation", "script_name": "UserCreation"} ] const backendtasks = [ {"id": 1, "name": "User Deletion", "script": "UserDeletion_V2"} ] const normalizedBackendTasks = backendtasks.reduce((acc, val) => ({...acc, [val.id]: val}), {}); const newFrontendTasks = frontendtasks.map((task) => normalizedBackendTasks[task.id] || task); return newFrontendTasks } console.log(getFrontendTasks())

通過刪除非常昂貴的嵌套for循環,創建映射表將時間復雜度從O(n^2)降低到O(n)

試試下面的代碼:

const map = {};
backendtasks.forEach(bt => (map[bt.id] = bt));

frontendtasks.forEach((ft, idx) => {
  if (map[ft.id]) {
    frontendtasks[idx] = map[ft.id];
    delete map[ft.id];
  }
});

frontendtasks = frontendtasks.concat(Object.values(map));

不知何故,我在任何創建新數組的解決方案中都沒有看到map() function,如下所示。

這將返回具有新值的新數組。 如您所見,它需要一個數組、一個 id(這可以是任何東西和任何類型)和一個回調。

在數組中搜索id並在找到時運行回調。 您想做的事情的有效方法。

在回調中,我在backendtasks上使用find()只是因為我需要找到具有相同id (id: 1) 的項目。

找到后,它從backendtasks返回該項目,然后通過在map() function 中返回該值來完成 function。

所以,這應該是O(n) ,考慮到回調只運行一次,在我看來它是一個更優雅的多次使用解決方案。

const frontendtasks: any[] = [];
const backendtasks: any[] = [];

const fn = (arr: any[], id: number, callback: (removed: any) => any) => {
  return arr.map((ft) => {
    if (ft.id !== id) return ft;
    else return callback(ft);
  });
};

fn(frontendtasks, 1, (rm) => backendtasks.find((id) => rm.id === id));
frontendtasks = [
                 {"id": 1, "name": "User Deletion", "script": "UserDeletion"},
                 {"id": 2, "name": "User Creation", "script_name": "UserCreation"}
                ]

backendtasks = [
                {"id": 1, "name": "User Deletion", "script": "UserDeletion_V2"}
               ]

我正在嘗試刪除 frontendtask 中 id = 1 的條目,並使用此代碼從 backendtask 推送條目。

if (backendtasks != 0) {
    for (updated_task in backendtasks ) {
        for (oldtask in frontendtasks) {
            if (frontendtasks[oldtask].id == backendtasks[updated_task].id) {
                frontendtasks[oldtask] = backendtasks[updated_task]
                delete backendtasks[updated_task];
                break;
            }
        }
    }
    for (new_task in backendtasks) {
        frontendtasks.unshift(backendtasks[new_task])
    }
}

這真的很慢,在瀏覽器中 CPU 達到 100%,有 700 個項目。 有沒有有效的方法來實現這一點?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM