在项目开发过程中遇到一个需求,需要把对象数组按指定的格式合并成一个二维数组。
原始数组:
let listArr = [
{ name: '张三', age: 18 },
{ name: '李四', age: 20 },
{ name: '王五', age: 17 },
{ name: '赵六', age: 25 },
{ name: '小宝', age: 23 },
{ name: '小寒', age: 19 }
];
目标数组:
let newArr = [
[ { name: '张三', age: 18 }, { name: '李四', age: 20 } ],
[ { name: '王五', age: 17 }, { name: '赵六', age: 25 } ],
[ { name: '小宝', age: 23 }, { name: '小寒', age: 19 } ]
];
方法1:索引填充
const newArr = Array.from({ length: arr.length/2 }).map( (item, i) => [arr[2*(i)], arr[2*(i+1)-1]]);
方法2:正则匹配
let arr = ['a','b','c','d','e','f'];
let newArr = JSON.stringify(arr).match(/"(.*?)","(.*?)"/g).map(x => {
//过滤一下分组后的item
return x.replace(/"(.*?)"/g, '$1').split(',');
});
方法3:增量分割
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
let newArr = arr.reduce((acc, cur, i) => {
// (1) 初次调用的返回值acc为初始值 [],它是一个数组,所以将 cur 元素合并进去(入栈)
// (2) 如果acc的栈顶依然是个数组,而不是字符串,就将 cur 元素合并进去(入栈后其实整个acc是一个数组和字符串的混合模式)
if (acc.length === 0 || Array.isArray( acc.at(-1) ) ) {
return [...acc, cur];
}
//取出栈顶元素,组合成一个新的二维数组(完成分组)
const lastVal = acc.pop();
return [...acc, [lastVal, cur]];
}, []);
方法4:减量分割
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
let newArr = arr.map( (item, i) => {
//由于每次减少两个元素,最终结果想要循环 arr.length/2 次,就需要在末尾处增加2个空元素
if ( i < 2 ) arr.push(null);
return arr.splice(0, 2); //每次减少两个元素并覆盖原数组
}).filter( x => x !== null );
方法5:矩阵法
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
// 创建一个 3x2 的辅助矩阵,用来记忆结果
let row = arr.length / 2;
let column = 2;
let matrix = Array(row).fill(0).map(x => Array(column).fill(0));
// 把矩阵的坐标和原数组的索引一一对应即可, 矩阵的坐标为 matrix[x][y]
for (let i = 0; i < row; i++) {
for (let j = 0; j < column; j++) {
matrix[i][j] = arr[j + i*2]; // 将笛卡尔坐标系转化成一维数组的角标
}
}
解法6:利用函数周期性
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
let { length } = arr;
let newArr = [];
arr.reverse(); //反转一下数组元素,我们使用while循环
while ( length > 0 ) {
length--;
// sin的周期性,Math.PI/2弧度相当于90度的角
if ( Math.abs( Math.sin(length * (Math.PI/2)) ) === 1 ) {
newArr.push([arr[length], arr[length-1]]);
}
}
解法7: 数组分割push
let array = [
{ title: '标题1', id: 1 }, { title: '标题2', id: 2 },
{ title: '标题3', id: 3 }, { title: '标题4', id: 4 },
{ title: '标题5', id: 5 }, { title: '标题6', id: 6 },
{ title: '标题7', id: 7 }, { title: '标题8', id: 8 },
{ title: '标题9', id: 9 }, { title: '标题10', id: 10 },
{ title: '标题11', id: 11 }, { title: '标题12', id: 12 },
{ title: '标题13', id: 13 }, { title: '标题14', id: 14 },
{ title: '标题15', id: 15 }, { title: '标题16', id: 16 },
{ title: '标题8', id: 8 }, { title: '标题9', id: 9 },
{ title: '标题10', id: 10 }, { title: '标题11', id: 11 },
{ title: '标题12', id: 12 }, { title: '标题13', id: 13 },
{ title: '标题14', id: 14 }, { title: '标题15', id: 15 },
{ title: '标题16', id: 16 }
]
let newArr = []
const handleInit = () => {
// 每页显示10条数据,一次push10条
let index = 10;
// 暂定每页显示10条数据,获取到需要循环的次数
for (let i = 0; i < Math.ceil(array.length / 10); i++) {
newArr.push(array.value.slice(i * 10, index));
index += 10;
}
console.log(newArr);
}