Cri*_* E. 2 javascript algorithm
该函数采用类似的输入路径,a.b.c并应输出一个嵌套结构 json,例如:
{
a: {
b: {
c: {}
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用迭代风格的算法是:
function stringToObj(path, obj) {
var parts = path.split(".");
var part;
while ((part = parts.shift())) {
if (typeof obj[part] != "object") obj[part] = {};
obj = obj[part]; // line 6
}
}
Run Code Online (Sandbox Code Playgroud)
当前使用情况:
let result = {};
stringToObj("a.b.c", result);
console.log(result); // outputs the json
Run Code Online (Sandbox Code Playgroud)
它依赖于在第 6 行改变 obj 参数。我不想依赖于传递result对象,而是在函数内部创建一个。这样做会导致不同的结果。所需的示例用法:
const result = stringToObj("a.b.c"); // result should be the json
Run Code Online (Sandbox Code Playgroud)
练习是为了学习。主要目标是了解为什么obj按如下方式删除和重写函数不能按预期工作:
function stringToObj(path) {
var obj = {};
var parts = path.split(".");
var part;
while ((part = parts.shift())) {
if (typeof obj[part] != "object") obj[part] = {};
obj = obj[part]; // line 6
}
return obj;
}
Run Code Online (Sandbox Code Playgroud)
按.s分割后,您可以使用reduceRight从最后一个属性 开始c,同时取一个空对象的初始值。在回调中,使用计算属性返回一个新对象,该对象包含正在迭代的属性处的旧对象:
const stringToObj = str => str.split('.').reduceRight(
(lastObj, prop) => ({ [prop]: lastObj }), {}
);
console.log(stringToObj('a.b.c'));Run Code Online (Sandbox Code Playgroud)
如果您不熟悉它,reduceRight就像reduce,除了它从数组中的最后一个元素开始向后迭代,而不是从数组的第一个元素开始并向前迭代。在每次迭代中,都会调用回调,其中第一个参数(此处为lastObj)是上次迭代返回的值,第二个参数是正在迭代的数组的当前项。
您还可以reverse使用属性数组reduce代替reduceRight,这可能一目了然更容易理解,但它有点不优雅:
const stringToObj = str => str.split('.').reverse().reduce(
(lastObj, prop) => ({ [prop]: lastObj }), {}
);
console.log(stringToObj('a.b.c'));Run Code Online (Sandbox Code Playgroud)
另外,不要混合var和let。如果您打算使用 ES2015 语法(您应该这样做),请考虑始终使用const,并且仅let 在必须重新分配时使用。永远不要使用var,它有太多值得在现代代码中使用的陷阱。