【问题标题】:Extract all specific properties from a nested array of objects从嵌套的对象数组中提取所有特定属性
【发布时间】:2019-11-01 19:34:33
【问题描述】:

我有一个嵌套的对象数组。我想得到一个对象,它只为我提供 onClick 属性作为键,值为 null。我能够导航到第一级,但我无法进一步向下导航。我该怎么做?

const headers = [{
    id: 'title1',
    title: 'Title 1',
    children: [
        {
            title: 'Children 1',
            child: [
                {
                    title: 'Child 1',
                      id: 'child1Id',
                      onClick: 'child1Click',
                      url: '/child1'
                },
                {
                    title: 'Child 2',
                    id: 'child2Id',
                    onClick: 'child2Click'
                }
            ]
      },
      {
            title: 'Children 2',
            child: [
                {
                    title: 'Child 3',
                    id: 'child3Id',
                    onClick: 'child3Click',
                },
                {
                    title: 'Child 4',
                    id: 'child4Id',
                    onClick: 'child4Click'
                }
            ]
      }
    ]
  },
  {
    id: 'title2',
    title: 'Title 2',
    privilege: '',
    children: [{
        title: 'Children 3',
        privilege: '',
        child: [{
            title: 'Child 5',
            id: 'child5Id',
            onClick: 'child3Click',
            url: '/child5',
            privilege: ''
          },
          {
            title: 'Child 6',
            id: 'child6Id',
            onClick: 'child6Click',
            url: '/child6',
            privilege: ''
          }
        ]
      },
      {
        title: 'Children 4',
        privilege: '',
        child: [{
            title: 'Child 7',
            id: 'child7Id',
            onClick: 'child7Click',
            url: '/child7',
            privilege: ''
          },
          {
            title: 'Child 8',
            id: 'child8Id',
            onClick: 'child8Click',
            url: '/child8',
            privilege: ''
          }
        ]
      }
      ]
    }
];

const routesMap = ({ onClick, children }) => (onClick ? { [onClick]: null } : _.flatMap(children, routesMap));

const routeStates = _.assign({}, ..._.flatMap(headers, routesMap));

console.log(routeStates)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

预期输出:

  {
      child1Click: null,
      child2Click: null,
      child3Click: null,
      child4Click: null,
      child5Click: null,
      child6Click: null,
      child7Click: null,
      child8Click: null,
  }

请指教。非常感谢任何帮助。

【问题讨论】:

    标签: javascript arrays object lodash


    【解决方案1】:

    使用 vanilla JS,您可以使用 3 个嵌套映射循环来获取 onClick 值,并返回一个具有该值作为属性的对象。使用Array.flat()转换为单个数组,并传播到Object.assign()得到一个对象。

    const fn = headers => Object.assign({}, ...headers
      .map(({ children }) => 
        children.map(({ child }) => child.map(({ onClick }) => ({ [onClick]: null })))
      ) // extract onClick values
      .flat(Infinity) // flatten to a single array
    )
    
    const headers = [{"id":"title1","title":"Title 1","children":[{"title":"Children 1","child":[{"title":"Child 1","id":"child1Id","onClick":"child1Click","url":"/child1"},{"title":"Child 2","id":"child2Id","onClick":"child2Click"}]},{"title":"Children 2","child":[{"title":"Child 3","id":"child3Id","onClick":"child3Click"},{"title":"Child 4","id":"child4Id","onClick":"child4Click"}]}]},{"id":"title2","title":"Title 2","privilege":"","children":[{"title":"Children 3","privilege":"","child":[{"title":"Child 5","id":"child5Id","onClick":"child3Click","url":"/child5","privilege":""},{"title":"Child 6","id":"child6Id","onClick":"child6Click","url":"/child6","privilege":""}]},{"title":"Children 4","privilege":"","child":[{"title":"Child 7","id":"child7Id","onClick":"child7Click","url":"/child7","privilege":""},{"title":"Child 8","id":"child8Id","onClick":"child8Click","url":"/child8","privilege":""}]}]}]
    
    const routeStates = fn(headers)
    
    console.log(routeStates)

    使用 lodash,您可以使用 _.flatMapDeep() 代替 Array.flat()

    const fn = headers => Object.assign({}, ...
      _.flatMapDeep(headers, ({ children }) => 
        _.map(children, ({ child }) => _.map(child, ({ onClick }) => ({ [onClick]: null })))
      ) // extract onClick values and flatte
    )
    
    const headers = [{"id":"title1","title":"Title 1","children":[{"title":"Children 1","child":[{"title":"Child 1","id":"child1Id","onClick":"child1Click","url":"/child1"},{"title":"Child 2","id":"child2Id","onClick":"child2Click"}]},{"title":"Children 2","child":[{"title":"Child 3","id":"child3Id","onClick":"child3Click"},{"title":"Child 4","id":"child4Id","onClick":"child4Click"}]}]},{"id":"title2","title":"Title 2","privilege":"","children":[{"title":"Children 3","privilege":"","child":[{"title":"Child 5","id":"child5Id","onClick":"child3Click","url":"/child5","privilege":""},{"title":"Child 6","id":"child6Id","onClick":"child6Click","url":"/child6","privilege":""}]},{"title":"Children 4","privilege":"","child":[{"title":"Child 7","id":"child7Id","onClick":"child7Click","url":"/child7","privilege":""},{"title":"Child 8","id":"child8Id","onClick":"child8Click","url":"/child8","privilege":""}]}]}]
    
    const routeStates = fn(headers)
    
    console.log(routeStates)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

    【讨论】:

    • 我可以将函数替换为 lodash 还是使用 lodash 提供更简化的答案,就像您在 stackoverflow.com/a/58470901/6731368 中的答案一样?
    • 使用 lodash,您可以使用 _.flatMapDeep() 保存一行。
    【解决方案2】:

    尝试循环访问它并尝试访问它,因为它是一个对象...

    for ( let i = 0; i < headers.length; i++ ) {
    
       for (let j = 0; j < headers[i].children.length; j++ ) {
    
         for (let k = 0; k < headers[i].children[j].child.length; j++ ) {
    
           console.log( headers[i].children[j].child[k].onClick);
    
        }
    
      }
    
    }
    

    它会打印如下...

      child1Click,
      child2Click,
      child3Click,
      child4Click,
      child5Click,
      child6Click,
      child7Click,
      child8Click
    

    如果您想将所有 childClick 设置为 null,请尝试添加这个。

    console.log( headers[i].children[j].child[k].onClick: null);
    

    希望对你有帮助

    【讨论】:

    • 需要注意的是,这仅适用于示例提供的这种非常具体的数据结构
    【解决方案3】:

    我借用了我找到的解决方案 here 来创建这个:

    var headers = [
        //...
    ];
    var newObj = {};
    
    function iterate(obj) {
        Object.keys(obj).forEach(key => {
    
        if (key === 'onClick') {
            newObj[obj[key]] = 'null';
        }
    
        if (typeof obj[key] === 'object') {
                iterate(obj[key])
            }
        })
    }
    
    iterate(headers);
    console.log(newObj);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 2022-11-13
      • 2013-10-11
      • 2020-07-20
      • 2021-07-17
      • 2019-03-23
      • 1970-01-01
      相关资源
      最近更新 更多