我试图将exif数据(对象)解析为Meteor网络应用程序的数组,同时保留一些树信息,即:
{exif:{size:{width:123}}}
会变成
[{key:width, value:123, path:["exif","size"]}]
这项工作正常,但objArray.path
始终为空,无论p
中的值是多少。一时兴起,我添加了depth: p.length
,并正确添加了此值。
因此,如果p = ["Channel statistics", "Red"]
,我希望objArray.path = ["Channel statistics", "Red"]
和depth = 2
,objArray.path
始终返回[]
。
我做错了什么?
parseObject = function (obj) {
po = function (obj, p, objArray) {
_.each(obj, function (v, k) {
if (typeof v==='object') {
objArray.push({ key: k, value: null, path: p, depth: p.length});
p.push(k);
return po(obj[k], p, objArray);
}
objArray.push({ key: k, value: v, path: p, depth: p.length });
});
p.pop();
return objArray;
};
return po(obj, [], []);
};
答案 0 :(得分:1)
每当您向p
中的对象添加objArray
时,您都会添加对p
也是对它的引用的数组的引用。因此,每次更改p
时,您基本上都会更改所有其他对象中的p
。由于您最终总是执行p.pop();
操作,因此在算法完成时推送到objArray的所有对象中p
为空。
解决方法是将p
的克隆插入到被推入objArray的对象中。
由于p
是一个普通字符串数组,我认为_.clone(p)应该足够了(它是一个浅拷贝,因此嵌套数组或对象将被引用复制)。
示例:
objArray.push({ key: k, value: v, path: _.clone(p), depth: p.length });
如果p
有嵌套对象/数组,则必须进行深层复制,这有点复杂,可以在google / stackoverflow上找到。