Lodash重新分配对象数组来构建树

Lodash re-assign array of objects to build a tree

本文关键字:数组 对象 构建 分配 新分配 Lodash      更新时间:2023-09-26

是否有一种简单的方法来重新分配由对象组成的数组到一个新的。我想使用Lodash库,但不知道如何将其拆分并连接。我需要这个来构建一个树使用jtree库

我有这样的东西:

 [
      {
        'text':'parent 1',
        'children': [
          {
            'text':'children 3'
          }
        ]
      },
      {
        'text':'parent 2',
        'children': []
      },
      {
        'text':'parent 3',
        'children': []
      },
      {
        'text':'parent 1',
        'children': [
          {
            'text':'children 1',
            'children': []
          },
          {
            'text':'children 2',
            'children': []
          }
        ]
      }
    ] 

我想在

转换后得到下一个
[
  {
    'text':'parent 2',
    'children': []
  },
  {
    'text':'parent 3',
    'children': []
  },
  {
    'text':'parent 1',
    'children': [
      {
        'text':'children 1',
        'children': []
      },
      {
        'text':'children 2',
        'children': []
      },
      {
        'text':'children 3'
      }
    ]
  }
] 

我想合并所有对象,如果'text'是相同的,并连接他们的孩子。

嵌套级别可以尽可能多,没有限制。

[
  {
    'text':'parent 1',
    'children': [
      {
        'text':'children 2',
        'children': [
          {
            'text':'parent 3',
            'children': [
              {
                'text':'parent 4',
                'children': [
                  ...
                ]
              },
            ]
          },
        ]
      }
    ]
  }
]

有可能吗?

如果您只想将具有相同'text'的对象组合并删除重复的对象,那么使用lodash的一个解决方案可能是:

var d = [{
  'text': 'parent 1',
  'children': []
}, {
  'text': 'parent 2',
  'children': []
}, {
  'text': 'parent 3',
  'children': []
}, {
  'text': 'parent 1',
  'children': [{
    'text': 'children 1',
    'children': []
  }, {
    'text': 'children 2',
    'children': []
  }]
}];
var res = _.reduce(d, (memo, o) => {
  var already = _.find(memo, o1 => o.text === o1.text);
  return already ? (already.children = already.children.concat(o.children), memo) : memo.concat(o);
}, []);
console.log(res);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>

这个解决方案不包括构建超过两个关卡的树。

假设你的数组结构代表树的结构:每个"层"代表树的一层,数组中同一层的对象在数组中的同一层,使用递归的一种可能的解决方案是:

var tree = [{
  'text': 'A',
  'children': [{
    'text': 'A.1',
    'children': [{
      'text': 'A.1.1',
      'children': [{
        'text': 'A.1.1.1',
        'children': [{
          'text': 'A.1.1.1.1'
        }]
      }, {
        'text': 'A.1.1.1',
        'children': [{
          'text': 'A.1.1.1.2'
        }]
      }]
    }]
  }, {
    'text': 'A.2',
    'children': [{
      'text': 'A.2.1',
      'children': [{
        'text': 'A.2.1.1',
        'children': []
      }]
    }]
  }]
}, {
  'text': 'B',
  'children': []
}, {
  'text': 'C',
  'children': []
}, {
  'text': 'A',
  'children': [{
    'text': 'A.3',
    'children': []
  }, {
    'text': 'A.4',
    'children': []
  }]
}];
function joinChildren(childrenArray) {
  return _.reduce(childrenArray, function(memo, o) {
    var already = _.find(memo, function(o1) {
      return o.text === o1.text;
    });
    return already ? (already.children = already.children.concat(o.children), memo) : memo.concat(o);
  }, []);
}
function joinChildrenRecursively(rootArray) {
  rootArray = joinChildren(rootArray);
  _.forEach(rootArray, obj => {
    if (_.isArray(obj.children)) {
      obj.children = joinChildrenRecursively(obj.children);
    }
  });
  return rootArray;
}
console.log(joinChildrenRecursively(tree));
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>

希望能有所帮助。

可以通过使用新的Object.values()和纯JS,您可以这样做;

var data =  [
      {
        'text':'parent 1',
        'children': [
          {
            'text':'children 3'
          }
        ]
      },
      {
        'text':'parent 2',
        'children': []
      },
      {
        'text':'parent 3',
        'children': []
      },
      {
        'text':'parent 1',
        'children': [
          {
            'text':'children 1',
            'children': []
          },
          {
            'text':'children 2',
            'children': []
          }
        ]
      }
    ],
   nested = Object.values(data.reduce((p,c) => (p[c.text] === undefined ? p[c.text] = {id: c.text, children: c.children}
                                                                        : p[c.text].children.push(...c.children),p), {}));
console.log(nested);