我有这个:
products = [
{
'id': 1
'name: 'test'
},
{
'id': 2
'name: 'test'
},
{
'id': 3
'name: 'test'
}
... etc, etc
]
我需要将其重组为:
products = [
row1: [
{
'id': 1
'name: 'test'
},
{
'id': 2
'name: 'test'
},
{
'id': 3
'name: 'test'
},
{
'id': 4
'name: 'test'
}
]
row2: [
{
'id': 5
'name: 'test'
},
{
'id': 6
'name: 'test'
},
{
'id': 7
'name: 'test'
},
{
'id': 8
'name: 'test'
}
]
row3: [.. etc, etc
]
困难的部分是每个组中的对象数量是使用变量设置的(在本例中变量为 4)。
如何使用 Typescript/Javascript 实现此目的?快把我逼疯了!
谢谢
最佳答案
选项 A:自定义分块/翻译方法
鉴于您希望在不考虑项内容的情况下将数组分成 block ,我建议使用一个简单的循环来按 block 大小逐步遍历数组,并在进行时对子集进行切片:
function chunk(array, chunkSize) {
// Create a plain object for housing our named properties: row1, row2, ...rowN
const output = {},
// Cache array.length
arrayLength = array.length;
// Loop variables
let arrayIndex = 0, chunkOrdinal = 1;
// Loop over chunks
while (arrayIndex < arrayLength) {
// Use slice() to get a chunk. Note the incrementing/assignment operations.
output[`row${chunkOrdinal++}`] = array.slice(arrayIndex, arrayIndex += chunkSize);
}
return output;
}
// Testing with a simplified demo array
console.table(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 4));
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script><style>.as-console-wrapper{display:block}</style><script>console.config({timeStamps:false,maximize:true})</script>
这比 reduce()
中的一些有一些优势建议。这个:
- 按 block 大小而不是 1 步;因此,它执行的迭代次数更少。
- 无需对每个指标进行重复、比较逻辑或计算。
- 定义每个
rowN
属性一次,永远不必检查它是否已经存在。 - 使用 native
Array.prototype.<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice" rel="noreferrer noopener nofollow">slice()</a>
方法来选择我们的子集,而不是一次推送一个单独的项目。
选项 B:Pre-chunk 和 Reduce
现在,如果你真的想使用 Array.prototype.<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce" rel="noreferrer noopener nofollow">reduce()</a>
,您可以使用更通用(可重用?)的方法对数组进行预分块,然后将生成的更短的二维数组缩减为所需的对象。这减轻了单独使用 reduce 的许多弱点:
function generateChunks(array, size) {
// Cache array.length
const length = array.length;
// Pre-size output array so we don't have to push/resize
const output = new Array(Math.ceil(length / size));
// Loop variables
let seekIndex = 0, outputIndex = 0;
// Loop over chunks
while (seekIndex < length) {
// Use slice() to get a chunk. Note the incrementing/assignment operations.
output[outputIndex++] = array.slice(seekIndex, seekIndex += size);
}
// Return our chunks
return output;
}
console.table(
// Pre-chunk
generateChunks([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 4)
// Reduce to translate into the desired object
.reduce((output, chunk, index) => {
output[`row${index + 1}`] = chunk;
return output;
},{})
);
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script><style>.as-console-wrapper{display:block}</style><script>console.config({timeStamps:false,maximize:true})</script>
这些方法中的任何一个,A 或 B,都应该比 the accepted reduce answer 快得多(~10 倍) ,特别是随着输入数组长度和/或 block 大小的增加。 这是一个 jsbench比较这些选项。
您的里程可能会有所不同。随意 fork 测试以尝试不同的输入数据或 block 大小。
关于javascript - 使用 typescript/javascript 将数组拆分为组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60007739/