JavaScript 中指定大小分割数组的一种实现

209 天前
 xiaohupro

今天分享一个使用 JavaScript 分割数组为多个自数组的方法实现。我使用它的场景如下:

给定一个数组 arr 和指定大小 fixed:

const arr = [
	{
		id: 1,
		name: 'name1'
	},
	{
		id: 2,
		name: 'name2'
	},
	{
		id: 3,
		name: 'name3'
	},
	{
		id: 4,
		name: 'name4'
	},
	{
		id: 5,
		name: 'name5'
	},
	{
		id: 6,
		name: 'name6'
	},
	{
		id: 7,
		name: 'name7'
	},
	{
		id: 8,
		name: 'name8'
	},
	{
		id: 9,
		name: 'name9'
	}
]
const fixed = 2;

期望的结果是生成一个数组,数组中包含 5 个数组,如下:

[
  [ { id: 1, name: 'name1' }, { id: 2, name: 'name2' } ],
  [ { id: 3, name: 'name3' }, { id: 4, name: 'name4' } ],
  [ { id: 3, name: 'name3' }, { id: 6, name: 'name6' } ],
  [ { id: 3, name: 'name3' }, { id: 6, name: 'name6' } ],
  [ { id: 3, name: 'name3' }, {} ]
]

按照 fixed 的大小分割,如果遇到不够 fixed 大小的,使用空对象填充。这种场景对表格数据填充需要等宽或者等数量会有所帮助。 具体实现代码如下:

/**
 *
 * @param {arr} 要分割的数组
 * @param {fixed} 指定分割的大小
 **/
function splitArr(arr, fixed) {
	let result = [];
	let size = arr.length;
	let len = Math.ceil(arr.length / fixed);//向上取整
	for(let i=0; i<len; i++){
		let tempArr = [];
		for(let j=0; j<fixed; j++){
			if((i*fixed)+j >= size){
				tempArr[j] = {}
			}else{
				tempArr[j] = arr[j];
			}
		}
		result.push(tempArr);
		if(arr.length > 0){
			arr.splice(i, fixed);
		}
	}
	return result;
}

const arr = [
	{
		id: 1,
		name: 'name1'
	},
	{
		id: 2,
		name: 'name2'
	},
	{
		id: 3,
		name: 'name3'
	},
	{
		id: 4,
		name: 'name4'
	},
	{
		id: 5,
		name: 'name5'
	},
	{
		id: 6,
		name: 'name6'
	},
	{
		id: 7,
		name: 'name7'
	},
	{
		id: 8,
		name: 'name8'
	},
	{
		id: 9,
		name: 'name9'
	}
]

const result = splitArr(arr, 2);

console.log(result);

希望本次分享的代码对你有所帮助,Thanks !!!

1645 次点击
所在节点    JavaScript
20 条回复
StrangerA
209 天前
为什么例子里分割后 id 为 3 的出现了 4 次,为 6 的出现了两次?
xjngbla
209 天前
没什么用,但是谢谢你
hay313955795
209 天前
function splitArr(arr, fixed) {
var index = 0;
var arrayLength = arr.length;
var result = [];
for (index = 0; index < arrayLength; index += fixed) {
var tempArr = arr.slice(index, index+fixed);
if(tempArr.length<fixed){
tempArr.splice(tempArr.length+1, 0, ...new Array(fixed-tempArr.length).fill({}));
}
result.push(tempArr);
}

return result;
}
var result = splitArr([{name:'1'},{name:'2'},{name:'3'},{name:'4'},{name:'5'},{name:'6'},{name:'7'},{name:'8'},{name:'9'}], 4);
console.log(result);

我的只有一个 for 循环。。
StrangerA
209 天前
```
import { groupBy } from 'lodash'

const arr = ...

const fixed = 2

const group = groupBy(arr, (item) => Math.floor((item['id'] + 1) / fixed))
const newArr = Object.values(group).map((item) =>
new Array(fixed).fill({}).map((_, index) => item[index] || {}),
)

console.log(newArr)
```

执行结果:

```
[
[ { id: 1, name: 'name1' }, { id: 2, name: 'name2' } ],
[ { id: 3, name: 'name3' }, { id: 4, name: 'name4' } ],
[ { id: 5, name: 'name5' }, { id: 6, name: 'name6' } ],
[ { id: 7, name: 'name7' }, { id: 8, name: 'name8' } ],
[ { id: 9, name: 'name9' }, {} ]
]
```

op 你要的是这样的吗
YorkWong
209 天前
之前写过一个将数组 array 分割成多个长度为 chunkSize 的子数组

splitArray(array, chunkSize = 500) {
const result = [];
const length = array.length;

for (let i = 0; i < length; i += chunkSize) {
result.push(array.slice(i, i + chunkSize));
}

return result;
},
Leviathann
209 天前
reduce 一下就行了
vvhy
209 天前
```
reshape = (a,dim,i=0,d=0)=>dim[d] ? Array(dim[d]).fill().map((_,j)=>reshape(a, dim, i * dim[d] + j, d + 1)) : a[i];
reshape([...Array(24).keys()], [2,3,4])
// [[[0,1,2,3],[4,5,6,7],[8,9,10,11]],[[12,13,14,15],[16,17,18,19],[20,21,22,23]]]
```
xiaohupro
209 天前
@StrangerA 是的,学到了,还有这种操作,没用过 lodash 这个库,完了去学习学习
iyiluo
209 天前
先把数组填充到可以整除的倍数,然后直接分割就行了
Rache1
209 天前
kneo
209 天前
逻辑问题就不说了,自己修去。提一个要注意的地方:返回新数组就不要修改原数组。
Rache1
209 天前
xiaohupro
209 天前
@StrangerA 感谢提醒,刚刚看了一下,应该将 splice(i, fixed) 改为 splice(0, fixed),因为每次删除时候应该从头开始,手残了,抱歉
xiaohupro
209 天前
@StrangerA 感谢提醒, 逻辑上有点问题,已 append
xiaohupro
209 天前
@kneo 逻辑上 splice 那里确实出了问题,已 append ,感谢。这种写法确实修改了原始数组,不是太好
StrangerA
209 天前
@huhailong1121 lodash 提供那些功能在某些语言里都是标准库能提供的存在了。简单的数组操作安心用 lodash 就成,不要浪费时间手搓,把省下来的时间用来写更重要的东西(甚至用来摸鱼都比手搓浪费时间强)
otakustay
209 天前
@StrangerA #4 你都 lodash 了,不直接用 chunk
StrangerA
209 天前
@otakustay 学艺不精,感谢指点
otakustay
209 天前
GPT 整出来的:

function chunk(array, size) {
return Array.from({ length: Math.ceil(array.length / size) }, (_, index) =>
array.slice(index * size, index * size + size)
);
}
forty
99 天前
let n = arr.length, f = fixed, pad = {};
let result = new Array(Math.ceil(n/f)).fill(0).map((_,i)
=>arr.slice(i*f,i*f+f).concat(new Array(i*f+f>n?fixed-n%fixed:0).fill(pad)));

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1038637

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX