目的:
我正在使用AngularJS和Lodash开发应用程序。我需要一个执行以下转换的函数:
这
{
a: 0,
b: {x: {y: 1, z: 2}},
c: 3
}
到
{
a: 0,
'b.x.y': 1,
'b.x.z': 2,
c: 3
}
现在,我正在使用递归函数遍历对象。目前,我的代码看起来像那样(不完整):
var obj = {},
keys, property, value;
var recur = function (mat) {
keys = Object.keys(mat);
for (var i = 0; i < keys.length; i++) {
property = keys[i];
value = mat[property];
if (isObj(value)) {
//debugger;
recur(value);
} else {
obj[property] = value;
}
}
}
recur({
a: 0,
b: {x: {y: 1, z: 2}},
c: 3
});
console.log(obj);
function isObj(value) {
return typeof value === "object";
}
我在调试时遇到的一个问题是:
我没有增加;在最高级别的递归调用期间,我仍为0。
任何人都知道为什么? 如果您知道进行此转换的任何其他方式,请分享。
亲切的问候。
答案 0 :(得分:2)
这是因为keys
声明的范围错误。它应该在内部 recur
中声明。因为它不是,当recur
递归时,keys
会被覆盖。
这不会使i
没有增加,但它确实意味着你的循环会在令人惊讶的时候终止,因为当你递归时keys
会发生变化。
property
和value
也应在recur
内宣布;通常,您可以在最里面的范围内声明变量。 (temp
根本不需要声明,因为你从不使用它。)
为了得到你的最终结果,显然你不得不改变,但你说代码是不完整的。这是循环无法正常工作的问题。
答案 1 :(得分:2)
为了转换有效对象,您可以使用迭代和递归方法来获取值及其值。
function convert(object) {
function iter(o, p) {
Object.keys(o).forEach(function (k) {
var q = p.concat(k);
if (o[k] && typeof o[k] === 'object') {
iter(o[k], q);
return;
}
object[q.join('.')] = o[k];
});
}
Object.keys(object).forEach(function (k) {
if (object[k] && typeof object[k] === 'object') {
iter(object[k], [k]);
delete object[k];
}
});
}
var object = { a: 0, b: { x: { y: 1, z: 2 } }, c: 3 };
convert(object);
console.log(object);
&#13;
单个迭代器/新结果
function convert(object) {
function iter(o, p) {
p = p ? p + '.' : '';
Object.keys(o).forEach(function (k) {
if (o[k] && typeof o[k] === 'object') {
iter(o[k], p + k);
return;
}
result[p + k] = o[k];
});
}
var result = {};
iter(object);
return result;
}
var object = { a: 0, b: { x: { y: 1, z: 2 } }, c: 3 };
console.log(convert(object));
&#13;
答案 2 :(得分:1)
你可以通过以下方式完成
let obj = {
a: 0,
b: {x: {y: 1, z: 2}},
c: 3
}
let result = {};
function rec(obj, parent){
if(typeof obj == 'object'){
for(let property in obj){
rec(obj[property], (parent == '' ? parent:parent+'.')+property);
}
}
else {
result[parent] = obj;
}
}
rec(obj, '');
console.log(result);
答案 3 :(得分:0)
感谢大家的帮助(尤其是@ T.J.Crowder指出我与范围有关的错误)。
我的完整代码(任何建议 - 与好/坏做法等有关 - 都欢迎):
var recur = function (obj, mat, parent) {
var keys = Object.keys(mat);
for (var i = 0; i < keys.length; i++) {
var property = keys[i];
var value = mat[property];
if (isObj(value)) {
recur(obj, value, parent ? parent + "." + property : property);
} else {
obj[parent ? parent + "." + property : property] = value;
}
}
return obj;
}
console.log(recur({}, {
a: 0,
b: {x: {y: 1, z: 2}},
c: 3
}));
function isObj(value) {
return typeof value === "object";
}