Return 对象中每个深度 属性 的字符串路径数组
Return array of string paths to every deep property within an object
我有一个丑陋的 1MB+ JSON 对象,它具有许多深层属性,包括包含嵌套对象的嵌套数组等。
我正在寻找一个函数,它可以 return 一个字符串数组 "paths" 用于给定对象中的每个 属性。
['obj.propA.first', 'obj.propA.second', 'obj.propB']
到目前为止,我的所有搜索都找到了另一个方向的解决方案。例如:获取路径字符串并获取 属性 值。
我的直觉告诉我必须有比重新发明轮子更好的方法。
提前致谢!
示例行为:
var ugly = {
a: 'a',
b: ['b1', 'b2'],
c: {
c1: 'c1',
c2: ['c2a', 'c2b'],
c3: {
c3a: 'c3a',
c3b: [['c3b']],
},
c4: [{c4a: 'c4a'}],
}
};
getPaths = function(obj) {
???
};
getPaths(ugly) = [
'a',
'b[0]',
'b[1]',
'c.c1',
'c.c2[0]',
'c.c2[1]',
'c.c3.c3a',
'c.c3.c3b[0][0]',
'c.c4[0].c4a',
];
这种情况有点奇怪,大概是在暗示架构层面有问题,但要明白那些东西有时是继承的and/or不可避免的。
node 4.2 版本的 es2015 中一个非常糟糕的可变递归实现:
function isPlainishObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
function propinator (obj, _paths, _currentPath) {
_paths = _paths || [];
if (typeof obj !== 'object') {
_paths.push(_currentPath);
} else {
for (let prop in obj) {
let path;
if (isPlainishObject(obj)) {
path = _currentPath && `${_currentPath}.${prop}` || prop;
} else {
path = _currentPath && `${_currentPath}[${prop}]` || prop;
}
propinator(
obj[prop],
_paths,
path
);
}
}
return _paths;
}
测试:
let assert = require('assert');
assert.deepEqual(propinator(ugly), [
'a',
'b[0]',
'b[1]',
'c.c1',
'c.c2[0]',
'c.c2[1]',
'c.c3.c3a',
'c.c3.c3b[0][0]',
'c.c4[0].c4a',
]);
这只是轻微测试(虽然可能很差)所以非常欢迎opinions/improvements。
我有一个丑陋的 1MB+ JSON 对象,它具有许多深层属性,包括包含嵌套对象的嵌套数组等。
我正在寻找一个函数,它可以 return 一个字符串数组 "paths" 用于给定对象中的每个 属性。
['obj.propA.first', 'obj.propA.second', 'obj.propB']
到目前为止,我的所有搜索都找到了另一个方向的解决方案。例如:获取路径字符串并获取 属性 值。
我的直觉告诉我必须有比重新发明轮子更好的方法。
提前致谢!
示例行为:
var ugly = {
a: 'a',
b: ['b1', 'b2'],
c: {
c1: 'c1',
c2: ['c2a', 'c2b'],
c3: {
c3a: 'c3a',
c3b: [['c3b']],
},
c4: [{c4a: 'c4a'}],
}
};
getPaths = function(obj) {
???
};
getPaths(ugly) = [
'a',
'b[0]',
'b[1]',
'c.c1',
'c.c2[0]',
'c.c2[1]',
'c.c3.c3a',
'c.c3.c3b[0][0]',
'c.c4[0].c4a',
];
这种情况有点奇怪,大概是在暗示架构层面有问题,但要明白那些东西有时是继承的and/or不可避免的。
node 4.2 版本的 es2015 中一个非常糟糕的可变递归实现:
function isPlainishObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
function propinator (obj, _paths, _currentPath) {
_paths = _paths || [];
if (typeof obj !== 'object') {
_paths.push(_currentPath);
} else {
for (let prop in obj) {
let path;
if (isPlainishObject(obj)) {
path = _currentPath && `${_currentPath}.${prop}` || prop;
} else {
path = _currentPath && `${_currentPath}[${prop}]` || prop;
}
propinator(
obj[prop],
_paths,
path
);
}
}
return _paths;
}
测试:
let assert = require('assert');
assert.deepEqual(propinator(ugly), [
'a',
'b[0]',
'b[1]',
'c.c1',
'c.c2[0]',
'c.c2[1]',
'c.c3.c3a',
'c.c3.c3b[0][0]',
'c.c4[0].c4a',
]);
这只是轻微测试(虽然可能很差)所以非常欢迎opinions/improvements。