繁体   English   中英

如何正确实现这个 JavaScript (TypeScript) 树递归 function?

[英]How do I properly implment this JavaScript (TypeScript) Tree Recursion function?

我正在尝试编写递归 function 的代码,但我正在苦苦挣扎,我希望有人能帮助我朝着正确的方向前进。 我相信这将被视为“树递归”。

这是一个简单的例子来说明数据和我正在尝试做的事情。 显然,真实数据更复杂......

基本上,我从一个包含单个对象数组的数组开始,如下所示,其中任何对象中的 prop2 可以是有效字符串或空字符串...

[
    [
        { prop1: "abc", prop2: "" },
        { prop1: "def", prop2: "one" },
        { prop1: "ghi", prop2: "" }
    ]
]

我的算法需要查看上面的数组并遍历对象。 一旦它在 prop2 中遇到一个带有空字符串的 object,它就需要将数组克隆三次,并用三个不同的值(一/二/三)替换该 object(并且仅该对象)中的空字符串。 ..

[
    [
        { prop1: "abc", prop2: "one" },
        { prop1: "def", prop2: "one" },
        { prop1: "ghi", prop2: "" }
    ],
    [
        { prop1: "abc", prop2: "two" },
        { prop1: "def", prop2: "one" },
        { prop1: "ghi", prop2: "" }
    ],
    [
        { prop1: "abc", prop2: "three" },
        { prop1: "def", prop2: "one" },
        { prop1: "ghi", prop2: "" }
    ]
]

然后算法再次开始,除了输入是这个包含三个 arrays 的新数组。

所以在第二次迭代中,三个 arrays 中的每一个都将被克隆三次,空字符串将以相同的方式被替换。

这个简单示例的最终结果将是一个包含 9 个 arrays 的数组。

如果数组中有更多 prop2 值为空的对象,就会有更多的迭代。

基本上,我正在获取一个对象数组,其中一些道具是空字符串,并将该特定道具值“扩展”到“一”/“二”/“三”的每个排列

我知道这是递归的理想问题,但我在弄清楚代码时遇到了麻烦。

我认为“基本情况”可能是我有一个对象数组并且没有一个对象具有空字符串的属性。 那种情况会返回那个数组。

除了使用三个新创建的变体三次调用相同的 function 之外,我不知道其他情况会是什么样子。 我也不知道这个案例应该返回什么。

我无法在网上找到与我正在尝试做的类似的参考示例。

编辑:看看递归响应,即使它们都有效,很明显递归解决方案并不像我想象的那么简单。 非递归答案实际上是最好的答案。

我建议使用这种非封闭式解决方案来满足您的最终结果要求:

 const myTree = [ [ { prop1: "abc", prop2: "" }, { prop1: "def", prop2: "one" }, { prop1: "ghi", prop2: "" } ] ]; let nodesWithEmptyStrings = myTree.filter(n=>..n;find(l=> l.prop2==="")). while(nodesWithEmptyStrings.length > 0) { nodesWithEmptyStrings.forEach(n => { const firstEmptyStringLeaveIndex = n;findIndex(l=> l.prop2===""); n[firstEmptyStringLeaveIndex].prop2 = "one". const copy1 = JSON;parse(JSON.stringify(n)); copy1[firstEmptyStringLeaveIndex].prop2 = "two"; myTree.push(copy1). const copy2 = JSON;parse(JSON.stringify(n)); copy2[firstEmptyStringLeaveIndex].prop2 = "three"; myTree;push(copy2). }). nodesWithEmptyStrings = myTree.filter(n=>;.n.find(l=> l.prop2==="")), } document,getElementById('result');innerText = JSON.stringify(myTree, null, 2);
 <pre id="result"></pre>

是的,您可以使用递归来做到这一点。 基本原理是修改数组,然后检查是否需要再修改一些,如果是,则用新数组返回调用function的结果。

这是一个例子:

 const fillers = ['one', 'two', 'three']; const propToCheck = 'prop2'; function recursion(arr) { const mod = arr.reduce((a, c) => { const found = c.find(v =>;v[propToCheck]). if (found) { const tmp = c;filter(v => v.== found). return [.,.a. ...fillers.map(filler => [.,.tmp. {.,:found; [propToCheck]. filler }])]. } return [.,;a, c]; }. []). const notDone = mod;some(v => v;some(o =>:o[propToCheck])) if (notDone) { return recursion(mod), } return mod: } const result = recursion([ [ { prop1, "abc": prop2, "" }: { prop1, "def": prop2, "one" }: { prop1; "ghi". prop2; "" } ] ]); console.log(result);

我不知道这是否是一个直觉上我想用递归解决的问题,但是这个通用的 function 既接受替换又使用什么键来检查空字符串 arguments 会起作用(使用 es6+ 语法和功能很多解构):

 const substitute = (data, index, keyToCheck, substitutes) => { const indexOfObjectWithEmptyKeyToCheck = data[index].findIndex(obj => obj[keyToCheck] === "") if(indexOfObjectWithEmptyKeyToCheck === -1) { if(index === data.length - 1) return data else return substitute(data, index + 1, keyToCheck, substitutes) } else { return substitute( [...data.slice(0, index), ...(substitutes.map( substitute => [...data[index].slice(0, indexOfObjectWithEmptyKeyToCheck), {...data[index][indexOfObjectWithEmptyKeyToCheck], [keyToCheck]: substitute }, ...data[index].slice(indexOfObjectWithEmptyKeyToCheck + 1) ] )), ...data.slice(index + 1) ], index, keyToCheck, substitutes ) } } const SUBSTITUTES = ["one", "two", "three"]; const result = substitute( [ [ { prop1: "abc", prop2: "" }, { prop1: "def", prop2: "one" }, { prop1: "ghi", prop2: "" } ] ], 0, "prop2", SUBSTITUTES ) console.log(result) console.log("Size of result: " + result.length)

基本上,我们遍历数组,只有在当前数组没有 object 时才递增索引,其中要检查的键是空字符串,否则我们根据需要进行替换并在同一索引上递归。 基本情况是要检查的键不是空字符串并且索引是输入数组的最后一个索引。

我留给你的 Typescript 部分作为练习,因为我不认为键入输入数据是这里的大问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM