使用属性将对象数组拆分为多维数组以对项目进行分组

问题描述 投票:0回答:2

我有一个对象数组,每个对象都带有一个

columnSpan
属性,其数值在 1 到 16 之间。

[
  {
    "columnSpan": 4,
    "id": "DatoCmsEntry-MaixsOYtSwS7mloD59Rvng"
  },
  {
    "columnSpan": 4,
    "id": "DatoCmsEntry-fEuNly9-QFiRh4DoUZ-Y_w"
  },
  {
    "columnSpan": 2,
    "id": "DatoCmsEntry-HsAgXDMHQkSXS_4lKSGfGA"
  },
  {
    "columnSpan": 2,
    "id": "DatoCmsEntry-BM-fSBruSM67IFzCrBSLBg"
  },
  {
    "columnSpan": 3,
    "id": "DatoCmsEntry-JPushhKGSBCwR_uWcwIFSw"
  },
  {
    "columnSpan": 3,
    "id": "DatoCmsEntry-Q0sfjP9ZQZSDZZVP_sI9ew"
  },
  {
    "columnSpan": 2,
    "id": "DatoCmsEntry-CdVhbQENQ4ib2z4w3wc20Q"
  },
  {
    "columnSpan": 2,
    "id": "DatoCmsEntry-Fn2U_0CuQDiBEOZLmS3ovQ"
  }
]

我需要将此数组拆分为一个多维数组,其中每个顶级项代表一个记录集合,其中总

columnSpan
为 16 或更少,保持原始顺序,如下所示:

[
  [
    {
      "columnSpan": 4,
      "id": "DatoCmsEntry-MaixsOYtSwS7mloD59Rvng"
    },
    {
      "columnSpan": 4,
      "id": "DatoCmsEntry-fEuNly9-QFiRh4DoUZ-Y_w"
    },
    {
      "columnSpan": 2,
      "id": "DatoCmsEntry-HsAgXDMHQkSXS_4lKSGfGA"
    },
    {
      "columnSpan": 2,
      "id": "DatoCmsEntry-BM-fSBruSM67IFzCrBSLBg"
    },
    {
      "columnSpan": 3,
      "id": "DatoCmsEntry-JPushhKGSBCwR_uWcwIFSw"
    }
  ],
  [
    {
      "columnSpan": 3,
      "id": "DatoCmsEntry-Q0sfjP9ZQZSDZZVP_sI9ew"
    },
    {
      "columnSpan": 2,
      "id": "DatoCmsEntry-CdVhbQENQ4ib2z4w3wc20Q"
    },
    {
      "columnSpan": 2,
      "id": "DatoCmsEntry-Fn2U_0CuQDiBEOZLmS3ovQ"
    }
  ]
]

关于如何实现这一目标的建议?

javascript arrays multidimensional-array
2个回答
0
投票

您可以通过保留 2 个额外变量来跟踪当前块和当前总数来实现此目的。无论如何,您需要一个数组来存储块。那么它只是一个循环。我不断添加当前块,直到它小于或等于 16,否则我将重置当前分块和总变量

const data  = [ { "columnSpan": 4, "id": "DatoCmsEntry-MaixsOYtSwS7mloD59Rvng" }, { "columnSpan": 4, "id": "DatoCmsEntry-fEuNly9-QFiRh4DoUZ-Y_w" }, { "columnSpan": 2, "id": "DatoCmsEntry-HsAgXDMHQkSXS_4lKSGfGA" }, { "columnSpan": 2, "id": "DatoCmsEntry-BM-fSBruSM67IFzCrBSLBg" }, { "columnSpan": 3, "id": "DatoCmsEntry-JPushhKGSBCwR_uWcwIFSw" }, { "columnSpan": 3, "id": "DatoCmsEntry-Q0sfjP9ZQZSDZZVP_sI9ew" }, { "columnSpan": 2, "id": "DatoCmsEntry-CdVhbQENQ4ib2z4w3wc20Q" }, { "columnSpan": 2, "id": "DatoCmsEntry-Fn2U_0CuQDiBEOZLmS3ovQ" } ]

const {chunked, currentChunk} = data.reduce((acc, curr) => {
  if (acc.currentTotal + curr.columnSpan <= 16) {
    acc.currentChunk.push(curr)
    acc.currentTotal += curr.columnSpan
  } else {
    acc.chunked.push(acc.currentChunk)
    acc.currentChunk = [curr]
    acc.currentTotal = curr.columnSpan
  }
  return acc
}, { chunked: [], currentChunk: [], currentTotal: 0 })

if (currentChunk.length) {
  chunked.push(currentChunk)
}

console.log(chunked)


0
投票

我会建议一个使用reduce的选项。该脚本按顺序遍历数组并对 ColumnSpan 进行计数。如果不超过16,则添加到当前数组,如果超过,则添加到下一个数组,依此类推。

const init = [
  {
    "columnSpan": 4,
    "id": "DatoCmsEntry-MaixsOYtSwS7mloD59Rvng"
  },
  {
    "columnSpan": 4,
    "id": "DatoCmsEntry-fEuNly9-QFiRh4DoUZ-Y_w"
  },
  {
    "columnSpan": 2,
    "id": "DatoCmsEntry-HsAgXDMHQkSXS_4lKSGfGA"
  },
  {
    "columnSpan": 2,
    "id": "DatoCmsEntry-BM-fSBruSM67IFzCrBSLBg"
  },
  {
    "columnSpan": 3,
    "id": "DatoCmsEntry-JPushhKGSBCwR_uWcwIFSw"
  },
  {
    "columnSpan": 3,
    "id": "DatoCmsEntry-Q0sfjP9ZQZSDZZVP_sI9ew"
  },
  {
    "columnSpan": 2,
    "id": "DatoCmsEntry-CdVhbQENQ4ib2z4w3wc20Q"
  },
  {
    "columnSpan": 2,
    "id": "DatoCmsEntry-Fn2U_0CuQDiBEOZLmS3ovQ"
  }
];

function groupBySum(init) {
  const group = init.reduce((acc, item) => {
    const summa = acc.sum + item.columnSpan;
    if (summa <= 16) {
      acc.delta.push(item);
      acc.sum = summa;
    } else {
      acc.sum = item.columnSpan;
      acc.result.push(acc.delta);
      acc.delta = [];
      acc.delta.push(item)
    }
    return acc;
  }, { sum: 0, result: [], delta: []});
  if (group.delta.length) {
    group.result.push(group.delta);
  }
  return group.result;
}

console.log(groupBySum(init))

© www.soinside.com 2019 - 2024. All rights reserved.