我正在尝试通过给定键从对象中检索嵌套值。我已经使其通过两个简单的forEach
循环工作,但我想使用一种更具功能性的方法来解决此问题。
这是到目前为止我得到的代码:
const object = {
screen: {
'[data-id="123"]': {
'font-family': 'Arial',
},
'[data-id="456"]': {
'background-color': 'red',
'font-family': 'Comic Sans',
},
},
};
const prop = 'font-family';
const props = [];
forEach(object, (selectors) => {
forEach(selectors, (selector) => {
if (prop in selector) {
props.push(selector[prop]);
}
});
});
console.log(props);
在这种情况下,该函数返回一个字体家族数组(由prop
const表示)。
我希望使用map
和reduce
之类的lodash函数,但我真的不知道从哪里开始。
谢谢。
答案 0 :(得分:1)
由于这是一个嵌套对象,因此它实际上取决于您要如何解决。如果以嵌套方式使用地图,则最终将得到嵌套数组。为了匹配您的输出,可以将嵌套数组展平。
_.flatten(_.map(object, (prop) => _.map(prop, (nestedProp) => nestedProp['font-family'])));
但是,如果您不想使用reduce而不是flatten,则可以从数组中减少嵌套数组。
_.reduce(_.map(object, (prop) => _.map(prop, (nestedProp) => nestedProp['font-family'])),(a, b) => [...a, ...b]);
在这一点上,我认为可读性受到了一些打击。如您所见,嵌套的地图函数可能会变得凌乱。
答案 1 :(得分:0)
您可以使用_.flatMap()
递归地迭代对象/数组,并使用等于prop的键来收集所有值:
const collect = (prop, obj) =>
_.flatMap(obj, (v, k) => {
if(k === prop) return v;
return _.isObject(v) ? collect(prop, v) : [];
});
const object = {
screen: {
'[data-id="123"]': {
'font-family': 'Arial',
},
'[data-id="456"]': {
'background-color': 'red',
'font-family': 'Comic Sans',
},
},
};
const result = collect('font-family', object);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
在香草JS中,您可以使用Object.entries()
和Array.flatMap()
:
const collect = (prop, obj) =>
Object.entries(obj).flatMap(([k, v]) => {
if(k === prop) return v;
return typeof v === 'object' && v !== null ? collect(prop, v) : [];
});
const object = {
screen: {
'[data-id="123"]': {
'font-family': 'Arial',
},
'[data-id="456"]': {
'background-color': 'red',
'font-family': 'Comic Sans',
},
},
};
const result = collect('font-family', object);
console.log(result);