一维数组按指定格式处理成二维数组

在项目开发过程中遇到一个需求,需要把对象数组按指定的格式合并成一个二维数组。

原始数组:
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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值