javascript - 将对象数组转换为包含对象的数组的最佳方法

标签 javascript angular performance typescript for-loop

以这个极其简化的对象数组为例:

[
    {
      createID: '1'
      // Many other properties...
    },
    {
      createID: '1'
      // Many other properties...
    },
    {
      createID: '1'
      // Many other properties...
    },
    {
      createID: '37'
      // Many other properties...
    },
    {
      createID: '37'
      // Many other properties...
    },
    {
      createID: '2'
      // Many other properties...
    },
    {
      createID: '2'
      // Many other properties...
    },
    {
      createID: '14'
      // Many other properties...
    },
  ];

给定这个数组,然后我使用对象 createID 属性创建一个包含对象 [[{..},{..}], [{..}] 的数组数组,..n]。我当前使用的前端框架(Angular v6)需要这个最终格式。

为了完成此任务,我使用以下代码,其中 tempArr 是一个数组,如上面提供的示例数组。

    let currentGroup: string = tempArr[0].createID;
    let tempGrouped: any[] = [];
    let childGroup: any[] = [];
    tempArr.forEach(item => {
      if (item.createID !== currentGroup) {
        tempGrouped.push(childGroup);
        childGroup = [];
        currentGroup = item.createID;
      }
      childGroup.push(item);
    });
    tempGrouped.push(childGroup);

这段代码工作正常。然而,我不禁相信在给定数据的情况下,一定有一种更高效、更优雅的方式将对象数组转换为包含对象的数组数组。

更新

重要的是要注意 createID只有 id 表示哪些对象应该分组在一起。因此,它们不需要按 createID 进行数字排序。此外,这些对象确实来自与其同级对象“分组”的服务器(相同的 createID),正如您在提供的给定示例数组中看到的那样。

最佳答案

您的示例具有所有彼此相邻的相同 ID。如果保证始终如此,那么循环并推送到新数组就足够了。但是,如果情况并非如此,您的解决方案将无法正确对项目进行分组。在这种情况下,使用哈希表仍然可以按具有相同渐近复杂度的 ID 进行分组。

您可以使用从 createdID 创建的键将对象分组到哈希表对象中。这将使您能够有效地对所有内容进行分组。然后从哈希表中取出对象:

let arr = [{createID: '1'},{createID: '1'},{createID: '1'},{createID: '37'},{createID: '37'},{createID: '2'},{createID: '2'},{createID: '14'},];

let o = arr.reduce((a, c) => {
    (a[c.createID] || (a[c.createID] = [])).push(c)
    return a
}, {} )
// o is a an object with createID keys pointing to arrays of grouped objects
// just take the values
console.log(Object.values(o))

根据问题编辑进行编辑

由于对象已经分组,因此没有比循环更好的方法了。如果您想要一个不添加临时数组的选项,您仍然可以使用 reduce(),它本质上与您当前的解决方案相同,但可能更加独立:

let tempArr = [{createID: '1'},{createID: '1'},{createID: '1'},{createID: '37'},{createID: '37'},{createID: '2'},{createID: '2'},{createID: '14'},];

let r = tempArr.reduce((a, c, i, self) => {
    if (i === 0 || self[i-1].createID !== c.createID) 
        a.push([])
    a[a.length - 1].push(c)
    return a
}, [])

console.log(r)

关于javascript - 将对象数组转换为包含对象的数组的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51505415/

相关文章:

javascript - 将回调传递给异步函数甚至再次包装它是否正常?

javascript - javascript 中的 onclick 事件监听器的多输入和多输出

javascript - 在 asp.net 中无法看到 JSColor 对象中的颜色面板

javascript - 调整多边形点路径(svg)内的图像大小并使其不被剪裁

performance - 当给定迭代次数和总时间时,如何找到算法的时间复杂度?

angular - 使用 Angular 组件将 Bootstrap 模板集成到 Angular 元素中

angular - 找不到模块@angular/core + angular2

Angular 2 typescript : Is it possible to pass an interface as a parameter into a function?

.net - 1000个组合框绑定(bind)

css - 指定 element.class { ... } 与仅指定 .class { ... } 的性能提升?