我想编写一个辅助函数,以从对象数组中的每个对象中解压缩特定的对象属性。有时,此属性将是顶级的,而其他时候,它将嵌套任意数量的级别。因此,这个问题的症结在于:如何基于可变长度的键名数组访问对象属性?
我希望有这样的东西:
const func = (arrOfObjects, ...keys) {
return arrOfObjects.map(object => {
return object[keys[0]][keys[1]] ... [keys[N]];
})
}
具有示例行为:
const input = [
{a: b: {c: 10}},
{a: b: {c: 11}},
{a: b: {c: 12}}
]
console.log(func(input, 'a', 'b', 'c'))
// [10, 11, 12]
console.log(func(input, 'a', 'b'))
// [{c: 10}, {c: 11}, {c : 12}]
我觉得必须有一个不错的ES6向导解决方案,但尚未找到它,因此,任何帮助将不胜感激!
干杯
P
答案 0 :(得分:1)
如果提供访问器,如[a, b, c[0], name]
,则可以编写一个自定义函数,如果在嵌套对象中找到该函数,则返回该值,否则返回未定义
let obj = {
a: 1,
b: 2,
c: {
d: 1,
e: [{
f: 3,
g: [{
z: 45
}]
}]
}
}
function findKeyFromPattern(obj, patternArr) {
let value = obj;
for(let i = 0; i < patternArr.length; i++) {
const arrmatch = patternArr[i].match(/(\w+)\[(\d+)\]/);
if(arrmatch) { // pattern matches and array accessor syntax
value = value[arrmatch[1]];
if(typeof value === 'object' && value !== null) {
value = value[arrmatch[2]];
} else {
return;
}
} else {
if(value[patternArr[i]]) {
value = value[patternArr[i]];
} else {
return;
}
}
}
return value;
}
console.log(findKeyFromPattern(obj, ['c', 'e[0]', 'g']));
console.log(findKeyFromPattern(obj, ['c', 'e[1]', 'g']))
答案 1 :(得分:1)
您可以使用Array#reduce
来获得简短的解决方案
const input = [
{a: { b: {c: 10}}},
{a: { b: {c: 11}}},
{a: { b: {c: 12}}}
]
console.log(func(input, ['a', 'b', 'c']))
// [10, 11, 12]
console.log(func(input, ['a', 'b']))
// [{c: 10}, {c: 11}, {c : 12}]
function func(input, props) {
return input.map(x => exctractByProps(x, props));
}
function exctractByProps(obj, props) {
return props.reduce(
(acc, prop) => typeof acc === 'object' && prop in acc ? acc[prop] : undefined,
obj
)
}
主要逻辑是获取传入的所有属性,然后尝试获取与obj[prop[0]][prop[1]][prop[2]]/* ... */[prop[n]]
相对应的值。如果对象的形状与prop
不匹配(例如,输入{a: 1}, ['a', 'b']
或{d: {c: 1}}, ['a', 'b']
),则函数返回undefined
。>
答案 2 :(得分:1)
根据您给我的问题和示例给出的答案。似乎输入的顺序将始终与对象嵌套匹配。所以这是我的解决方案:
const func = (arrOfObjects, ...keys) => {
return arrOfObjects.map(object => {
let obj = object, integer = keys.length;
for (let index = 0; index < integer; index++) {
obj = obj[keys[index]];
if(obj === undefined) break;
}
return obj;
});
};
const input = [
{ a: { b: { c: 10 } } },
{ a: { b: { c: 11 } } },
{ a: { b: { c: 12 } } }
];
console.log(func(input, "a", "b", "c"));
// [10, 11, 12]
console.log(func(input, "a", "b"));
// [{c: 10}, {c: 11}, {c : 12}]
不幸的是,您所期望的并没有像JavaScript魔术这样的东西。 注意:当对象内的键的顺序以随机深度嵌套时,此代码将不起作用。但是对于您要解决的问题,这应该可以正常工作。另外,我尝试尽可能保留您的初始代码