【问题标题】:flatten javascript array of objects展平 javascript 对象数组
【发布时间】:2018-02-24 20:51:28
【问题描述】:

我有一个具有层次结构的对象数组,如下所示:

[
    {name: 'ParentOne', children: [
        {name: 'ParentOneChildOne'},
        {name: 'ParentOneChildTwo', children: [
            {name: 'ParentOneChildTwoGrandChildOne'},
        ]},
    ]}, 
    {name: 'ParentTwo', children: [
        {name: 'ParentTwoChildOne', children: [
           {name: 'ParentTwoChildOneGrandChildOne'},
           {name: 'ParentTwoChildOneGrandChildTwo'}
        ]},
        {name: 'ParentTwoChildTwo'}
    ]}
];

我想把它弄平:

[
    {name: 'ParentOne'},
    {name: 'ParentOneChildOne'},
    {name: 'ParentOneChildTwo'},
    {name: 'ParentOneChildTwoGrandChildOne'},
    {name: 'ParentTwo'},
    {name: 'ParentTwoChildOne'},
    {name: 'ParentTwoChildOneGrandChildOne'},
    {name: 'ParentTwoChildOneGrandChildTwo'},
    {name: 'ParentTwoChildTwo'}
]

我已经尝试过_.flatten()_.flatMap(),但它不能产生我需要的东西。最好使用 lodash.jsunderscore.js 实现它的最佳方法是什么。

【问题讨论】:

    标签: javascript underscore.js lodash flatten


    【解决方案1】:

    不需要下划线/lodash。

    const arr = [
        {name: 'ParentOne', children: [
            {name: 'ParentOneChildOne'},
            {name: 'ParentOneChildTwo', children: [
                {name: 'ParentOneChildTwoGrandChildOne'},
            ]},
        ]}, 
        {name: 'ParentTwo', children: [
            {name: 'ParentTwoChildOne', children: [
               {name: 'ParentTwoChildOneGrandChildOne'},
               {name: 'ParentTwoChildOneGrandChildTwo'}
            ]},
            {name: 'ParentTwoChildTwo'}
        ]}
    ];
    
    function flatten(arr) {
        return arr? arr.reduce((result, item) => [
            ...result,
            { name: item.name },
            ...flatten(item.children)
        ], []) : [];
    }
    
    console.log(flatten(arr));

    【讨论】:

      【解决方案2】:

      我会使用.reduce 和递归来做到这一点。这是我使用 Array.reduce 的实现,但你可以使用下划线的 reduce 函数做很多相同的事情。

      const arr = [
          {name: 'ParentOne', children: [
              {name: 'ParentOneChildOne'},
              {name: 'ParentOneChildTwo', children: [
                  {name: 'ParentOneChildTwoGrandChildOne'},
              ]},
          ]}, 
          {name: 'ParentTwo', children: [
              {name: 'ParentTwoChildOne', children: [
                 {name: 'ParentTwoChildOneGrandChildOne'},
                 {name: 'ParentTwoChildOneGrandChildTwo'}
              ]},
              {name: 'ParentTwoChildTwo'}
          ]}
      ];
      
      function flatten(arr) {
         return arr.reduce((result, current) => {
            if (current.children) {
               const children = flatten(current.children);
               delete current.children;
               result.push(current);
               result.push(...children);
            } else {
               result.push(current);
            }
            return result;
         }, [])
      }
      
      console.log(flatten(arr));

      【讨论】:

        【解决方案3】:

        您可以尝试调整this answer 中给出的flatten 函数,并将逻辑稍微扭曲到对象的结构。

        //Your object
        var data = [{
            name: 'ParentOne',
            children: [{
                name: 'ParentOneChildOne'
              },
              {
                name: 'ParentOneChildTwo',
                children: [{
                  name: 'ParentOneChildTwoGrandChildOne'
                }, ]
              },
            ]
          },
          {
            name: 'ParentTwo',
            children: [{
                name: 'ParentTwoChildOne',
                children: [{
                    name: 'ParentTwoChildOneGrandChildOne'
                  },
                  {
                    name: 'ParentTwoChildOneGrandChildTwo'
                  }
                ]
              },
              {
                name: 'ParentTwoChildTwo'
              }
            ]
          }
        ];
        
        //georg's flatten function
        flatten = function(x, result, prefix) {
          if (_.isObject(x)) {
            _.each(x, function(v, k) {
              flatten(v, result, prefix ? prefix + '_' + k : k)
            })
          } else {
            result[prefix] = x
          }
          return result
        }
        
        //using the function on your data
        result = flatten(data, {});
        console.log(result);
        <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

        这有帮助吗?

        【讨论】:

          【解决方案4】:

          递归函数适用于任何深度的迭代。

          带有一些 ES2015 和 LoDash/Underscore

          var arr = [{
            name: 'ParentOne',
            children: [{
              name: 'ParentOneChildOne'
            }, {
              name: 'ParentOneChildTwo',
              children: [{
                name: 'ParentOneChildTwoGrandChildOne'
              }, ]
            }, ]
          }, {
            name: 'ParentTwo',
            children: [{
              name: 'ParentTwoChildOne',
              children: [{
                name: 'ParentTwoChildOneGrandChildOne'
              }, {
                name: 'ParentTwoChildOneGrandChildTwo'
              }]
            }, {
              name: 'ParentTwoChildTwo'
            }]
          }];
          
          var res = _.reduce(arr, (a, b) => {
            (rec = item => {
              _.each(item, (v, k) => (_.isObject(v) ? rec(v) : a.push(_.zipObject([k], [v]))))
            })(b);
            return a;
          }, []);
          
          console.log(res);
          <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

          【讨论】:

            【解决方案5】:

            您可以使用一些破坏并使用递归函数来收集所有想要的项目。

            var array = [{ name: 'ParentOne', children: [{ name: 'ParentOneChildOne' }, { name: 'ParentOneChildTwo', children: [{ name: 'ParentOneChildTwoGrandChildOne' },] },] }, { name: 'ParentTwo', children: [{ name: 'ParentTwoChildOne', children: [{ name: 'ParentTwoChildOneGrandChildOne' }, { name: 'ParentTwoChildOneGrandChildTwo' }] }, { name: 'ParentTwoChildTwo' }] }],
                flat = (r, { name, children = [] }) => [...r, { name }, ...children.reduce(flat, []) ],
                result = array.reduce(flat, []);
                
            console.log(result);
            .as-console-wrapper { max-height: 100% !important; top: 0; }

            在 EDGE 上,您需要使用不同的默认值。

            var array = [{ name: 'ParentOne', children: [{ name: 'ParentOneChildOne' }, { name: 'ParentOneChildTwo', children: [{ name: 'ParentOneChildTwoGrandChildOne' },] },] }, { name: 'ParentTwo', children: [{ name: 'ParentTwoChildOne', children: [{ name: 'ParentTwoChildOneGrandChildOne' }, { name: 'ParentTwoChildOneGrandChildTwo' }] }, { name: 'ParentTwoChildTwo' }] }],
                flat = (r, { name, children }) => [...r, { name }, ...(children || []).reduce(flat, []) ],
                result = array.reduce(flat, []);
                
            console.log(result);
            .as-console-wrapper { max-height: 100% !important; top: 0; }

            【讨论】:

              猜你喜欢
              • 2015-05-23
              • 2023-01-11
              • 1970-01-01
              • 2020-07-19
              • 2021-12-25
              • 2023-03-20
              • 1970-01-01
              • 2018-07-09
              • 2020-07-11
              相关资源
              最近更新 更多