【问题标题】:Javascript algorithm to find objects in arrayJavascript算法在数组中查找对象
【发布时间】:2021-05-08 18:18:26
【问题描述】:

我有一个包含项目数据的对象数组。每个项目都有一个 ID 和 2 个包含项目 ID 的数组,这将在之前和之后发生。 像这样:

let projects = [];

projects[0] = {
    id: "ID_123",
    before: [],
    after: ["ID_523"],
}

projects[1] = {
    id: "ID_523",
    before: ["ID_123"],
    after: ["ID_523","ID_827"],
}

我想找到所有相互依赖的项目并将它们添加到同一个子组中。所以我循环遍历数组并从以前没有项目发生的项目开始。然后我继续添加之后发生的第一个项目,将其添加到同一个子组并继续这样做,直到之后没有更多项目发生。 我的算法:

let subgroup = 0;
// loop through project array
for (let i=0; i<projects.length; i++) {
    let next = projects[i]; // next contains the next project in the row
    // find projects that have no projects happening before
    if ((!next.hasOwnProperty('subgroup')) && (next.before.length == 0)) {
        // do this as long as the next project has projects happening after
        while (next.after.length > 0) {
            // find the array-key of the first project happening afterwards
            let key;
            for (let n=0; n<projects.length; n++) {
                if (projects[n].id == next.after[0]) {
                    key = n;
                    break;
                }
            }
            // set the subgroup of the project with the key from above
            projects[key].subgroup = subgroup;
            // set the next project
            next = projects[key];
        }
        subgroup++;
    }
}

不幸的是,该算法无法按预期工作,某些项目根本无法获得分配的子组。我花了几天时间寻找错误,但我找不到它。

希望有人能告诉我我做错了什么。提前致谢!

【问题讨论】:

  • 作为澄清,当您说“相互依赖”时,您是什么意思?你的意思是像 A 依赖于 B 和 B 依赖于 A 这样的循环依赖,还是项目 A 依赖于项目 B 的完成而项目 C 依赖于项目 A 的完成。
  • 我有一种预感,这个问题可以使用像拓扑排序这样的图算法来解决,或者如果它更复杂,那么可能是 tarjan 的算法。但是,如果您能阐明“相互依赖的意思”是什么,那将会有所帮助。

标签: javascript arrays algorithm object


【解决方案1】:

您缺少连接,因为您的代码仅查看 after[0],而不查看可能出现在 after 属性中的任何其他 ID。更重要的是,您还应该通过before检查依赖关系,因为您可能会从不同的前辈获得一个项目,而这些项目应该都属于同一个子组。

您还可以避免为需要查找的每个 ID 重复数据:而是创建一个 Map ,该 Map 将通过其 ID 对每个项目进行键控。

然后,为确保您处理了 afterbefore 属性中的所有条目,请执行广度优先搜索:将所有这些依赖项目添加到队列中,忽略已访问的项目(我将使用设置):

let projects = [{
    id: "ID_123",
    before: [],
    after: ["ID_523"],
}, {
    id: "ID_523",
    before: ["ID_123"],
    after: ["ID_523","ID_827"],
}, {
    id: "ID_827",
    before: ["ID_523"],
    after: [],
}, {
    id: "ID_999",
    before: [],
    after: [],
}];


let subgroup = 0;
let map = new Map(projects.map(p => [p.id, p]));
for (let project of projects) {
    if (project.before.length === 0 && !("subgroup" in project)) {
        let todo = new Set([project]);
        for (let project of todo) {
            project.subgroup = subgroup;
            for (let next of project.after) todo.add(map.get(next));
            for (let prev of project.before) todo.add(map.get(prev));
        }
        subgroup++;
    }
}

console.log(projects);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多