如何对 javascript 对象数组进行排序,这些对象指定了它们之间的先决条件?

How can I sort a javascript array of objects that specify prerequisites between them?

我有一个对象数组,用于确定应首先显示哪些对象。这个数组的一个例子是:

[
    {
        "id": "b94ae1a5-c6b2-4e45-87cd-a4036fdb7870",
        "prerequisites_ids": [
            "2a4fdd9c-45d0-49d9-a0eb-ba5a0464f2b1"
        ]
    },
    {
        "id": "ef7d2415-808f-4efc-939e-2692f38a5ee7",
        "prerequisites_ids": [
            "74e41a2c-e74e-4016-bb2c-f2e84c04fe92"
        ]
    },
    {
        "id": "74e41a2c-e74e-4016-bb2c-f2e84c04fe92",
        "prerequisites_ids": []
    },
    {
        "id": "2a4fdd9c-45d0-49d9-a0eb-ba5a0464f2b1",
        "prerequisites_ids": [
            "ef7d2415-808f-4efc-939e-2692f38a5ee7"
        ]
    }
]

我该如何排序才能得到这个?

[
    {
        "id": "74e41a2c-e74e-4016-bb2c-f2e84c04fe92",
        "prerequisites_ids": []
    },
    {
        "id": "ef7d2415-808f-4efc-939e-2692f38a5ee7",
        "prerequisites_ids": [
            "74e41a2c-e74e-4016-bb2c-f2e84c04fe92"
        ]
    },
    {
        "id": "2a4fdd9c-45d0-49d9-a0eb-ba5a0464f2b1",
        "prerequisites_ids": [
            "ef7d2415-808f-4efc-939e-2692f38a5ee7"
        ]
    },
    {
        "id": "b94ae1a5-c6b2-4e45-87cd-a4036fdb7870",
        "prerequisites_ids": [
            "2a4fdd9c-45d0-49d9-a0eb-ba5a0464f2b1"
        ]
    }
]

我试过创建自定义函数:

export function comparePrerequisites(a, b) {
  if (!a.prerequisites_ids) {
    return -1
  }
  if (a.prerequisites_ids.includes(b.id)) {
    return 1;
  }
}
data.sort(comparePrerequisites)

但似乎不起作用。提前致谢!

我们这里有 topological sort 的要求。这不是 sort 方法的工作。相反,您可以使用递归(DFS 遍历)深入到已收集的依赖项或叶(无依赖项)。

这是一个实现:

function topologicalSort(tasks) {
    const visited = new Set;
    const taskMap = new Map(tasks.map(task => [task.id, task]));
    
    function dfs(tasks) {
        for (let task of tasks) {
            if (!visited.has(task.id)) {
                dfs(task.prerequisites_ids.map(id => taskMap.get(id)));
            }
            visited.add(task);
        }
    }
    
    dfs(tasks);
    return [...visited];
}

// Demo on your example:
let tasks = [{"id": "b94ae1a5-c6b2-4e45-87cd-a4036fdb7870","prerequisites_ids": ["2a4fdd9c-45d0-49d9-a0eb-ba5a0464f2b1"]},{"id": "ef7d2415-808f-4efc-939e-2692f38a5ee7","prerequisites_ids": ["74e41a2c-e74e-4016-bb2c-f2e84c04fe92"]},{"id": "74e41a2c-e74e-4016-bb2c-f2e84c04fe92","prerequisites_ids": []},{"id": "2a4fdd9c-45d0-49d9-a0eb-ba5a0464f2b1","prerequisites_ids": ["ef7d2415-808f-4efc-939e-2692f38a5ee7"]}];
console.log(topologicalSort(tasks));