【问题标题】:Get a nested value with lodash使用 lodash 获取嵌套值
【发布时间】:2019-06-24 20:52:53
【问题描述】:

我正在尝试通过给定键从对象中检索嵌套值。我已经使用两个简单的 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 表示)。

我希望使用像 mapreduce 这样的 lodash 函数,但我真的不知道从哪里开始。

提前致谢。

【问题讨论】:

    标签: javascript object lodash


    【解决方案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]);
    

    在这一点上,我认为可读性受到了影响。如您所见,嵌套的地图函数可能会变得混乱。

    【讨论】:

    • 鉴于 OP 的代码使用嵌套循环(而不是直接针对 object.screen),我想知道是否还有其他属性需要考虑。
    • 是的,还有其他属性。屏幕只是其中之一。因此嵌套循环。
    • 感谢您的快速回复!使用 flatten 的第一个选项确实是最易读的解决方案。
    【解决方案2】:

    您可以使用_.flatMap() 递归地迭代一个对象/数组,并使用等于该道具的键收集所有值:

    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);

    【讨论】:

      猜你喜欢
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      • 2017-01-20
      • 2014-02-27
      相关资源
      最近更新 更多