递归遍历数组数组(算法问题)

loop threw an array of arrays in recursion (algorithm problem)

我有点想创建一个在工厂中最广为人知的功能。一种轮换系统,人们交换他们的位置,而其他人则在休息。

通过 DragnDrop I create/add/update 一个地图并将此地图转换为数组数组,如下所示:

let example1 = [
    ['John',    ['99', '1']],
    ['Jo',      ["1", "3"]],
    ["Alpha",   ["99", "4"]],
    ["Beta",    ["3", "2"]],
    ["Gamma",   ["2", "99"]],
    ["Delta",   ["4", "5"]],
    ["Maria",   ["5", "6"]],
    ["Epsilon", ["6", "99"]],
];

第一个数字是位置,第二个数字是 位置。 数字 99 代表休息时的蜜蜂。 上面例子的输出应该是这样的:

outputExample1 = [
    ["John", "1", "3", "2"], 
    ["Alpha", "4, "5", "6"] 
]

所以每个序列和递归都应该以 breaker(=数字 99)开始并以 breaker 结束。 在上面的例子中:将“john”放在第一站后,它应该“搜索”来自第一站的 guy/ladie 是“现在”的位置。在这个例子中,他在 3。现在再次搜索他汀类药物 3 现在所在的位置。 (=2) ... 直到数字为 99,在此示例中就是这种情况。 这就是为什么我开始在 'activ'(<99) 和 'breakers'(==99) 中过滤原始数组。 我尝试了很多方法并不断失败(while 循环以无限循环结束,输出完全错误),因为我没有找到一个好的递归。

任何提示都非常准确

PS:请考虑以上数组已“完成”以提供一个很好的示例,可能无法即时完成(通过拖放)。意思是:如果我开始拖动,sequenze肯定没有完成。

编辑:肯定会有至少一个“99”。如果不是没有序列也没有输出。 'new position' 除了 99er 之外也没有重复。 (无论如何都是首发

您可以采用顺序方法并按顺序访问所有节点。然后为最顶部的项目取一个嵌套的 属性 并保持与节点的关系。最后 return 只是顶部节点。

如有必要,获取 key/value 对数组的结果条目。

const
    data = [['John',    ['99', '1']], ['Jo',      ["1", "3"]], ["Alpha",   ["99", "4"]], ["Beta",    ["3", "2"]], ["Gamma",   ["2", "99"]], ["Delta",   ["4", "5"]], ["Maria",   ["5", "6"]], ["Epsilon", ["6", "99"]]],
    relations = data
        .reduce((r, [top, [from, to]]) => {
            if (to === '99') return r;
            if (from === '99') {
                r[to] = r.top[top] = [to];
            } else {
                r[from].push(to);
                r[to] = r[from];
            }
            return r;
        }, { top: {} })
        .top;

console.log(relations);
.as-console-wrapper { max-height: 100% !important; top: 0; }

没有 reduce.

的版本

const
    data = [['John',    ['99', '1']], ['Jo',      ["1", "3"]], ["Alpha",   ["99", "4"]], ["Beta",    ["3", "2"]], ["Gamma",   ["2", "99"]], ["Delta",   ["4", "5"]], ["Maria",   ["5", "6"]], ["Epsilon", ["6", "99"]]],
    temp = {},
    relations = {};

for (const [top, [from, to]] of data) {
    if (to === '99') continue;
    if (from === '99') {
        temp[to] = relations[top] = [to];
    } else {
        temp[from].push(to);
        temp[to] = temp[from];
    }
}

console.log(relations);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Nina 的回答很好,只要您的数据始终像示例中那样排序即可。如果没有,那么这可能会有所帮助:

const cycleUntil = (schedule, x, [_, [f, t]] = schedule .find (([_, [f]]) => x == f)) => 
  f == 99 ? [] : [f, ... cycleUntil (schedule, t)]

const transform = (schedule) => 
  schedule .filter (([n, [f]]) => f == '99') 
           .map (([n, [f, t]]) => [n, ... cycleUntil (schedule, t)])

const example1 = [['John', ['99', '1']], ['Jo', ["1", "3"]], ["Alpha", ["99", "4"]], ["Beta", ["3", "2"]], ["Gamma", ["2", "99"]], ["Delta", ["4", "5"]], ["Maria", ["5", "6"]], ["Epsilon", ["6", "99"]] ]
console .log (transform (example1))

const example2 = [...example1, ["Zeta", ["99", "7"]], ["Eta", ["7", "10"]], ["Theta", ["8", "99"]], ["Iota", ["9", "8"]], ["Kappa", ["10", "9"]]]
console .log (transform (example2))
.as-console-wrapper {max-height: 100% !important; top: 0}

这里我们的 transform 函数查找所有以 '99' 开头的元素和 returns 与它们关联的名称以及调用 cycleUntil 函数的结果,该函数采用一个站和整个时间表和 returns 一个包含该站的数组,以及递归地,该 to 站位于其 from 位置的元素。

如果数据构造不正确,这将失败。它几乎肯定需要一些错误检查以确保数据完整。但我会把它留作练习。