递归遍历数组数组(算法问题)
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
位置的元素。
如果数据构造不正确,这将失败。它几乎肯定需要一些错误检查以确保数据完整。但我会把它留作练习。
我有点想创建一个在工厂中最广为人知的功能。一种轮换系统,人们交换他们的位置,而其他人则在休息。
通过 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
位置的元素。
如果数据构造不正确,这将失败。它几乎肯定需要一些错误检查以确保数据完整。但我会把它留作练习。