如何在TypeScript/JavaScript中按catid将对象数组转为二维数组
按catid分组数组为二维数组的实现方案
给定如下一维对象数组:
const arr1 = [{catid: 1, name: 'mango', category: 'fruit'}, {catid: 2, name: 'potato', category: 'veg'}, {catid: 3, name: 'chiken', category: 'nonveg'},{catid: 1, name: 'apple', category: 'fruit'}, {catid: 1, name: 'banana', category: 'fruit'}];
我们需要按对象的catid属性分组,转换为目标二维数组:
const arr2 = [[{catid: 1, name: 'mango', category: 'fruit'},{catid: 1, name: 'apple', category: 'fruit'}, {catid: 1, name: 'banana', category: 'fruit'} ],[{catid: 2, name: 'potato', category: 'veg'}],[{catid: 3, name: 'chiken', category: 'nonveg'}]]
下面是两种在JavaScript/TypeScript中实现的常用方式:
方法一:使用Array.reduce() + Object.values()
利用reduce构建一个以catid为键、对应分组数组为值的对象,再通过Object.values提取所有分组数组,得到最终的二维数组:
const arr1 = [{catid: 1, name: 'mango', category: 'fruit'}, {catid: 2, name: 'potato', category: 'veg'}, {catid: 3, name: 'chiken', category: 'nonveg'},{catid: 1, name: 'apple', category: 'fruit'}, {catid: 1, name: 'banana', category: 'fruit'}]; // 构建分组对象 const groupedObj = arr1.reduce((acc, item) => { // 初始化当前catid对应的数组(如果不存在) if (!acc[item.catid]) { acc[item.catid] = []; } // 将当前元素推入对应分组 acc[item.catid].push(item); return acc; }, {}); // 转换为二维数组 const arr2 = Object.values(groupedObj); console.log(arr2);
方法二:使用Map数据结构
Map的键值对结构天生适合分组场景,遍历数组构建Map后,再将Map的值转换为数组即可:
const arr1 = [{catid: 1, name: 'mango', category: 'fruit'}, {catid: 2, name: 'potato', category: 'veg'}, {catid: 3, name: 'chiken', category: 'nonveg'},{catid: 1, name: 'apple', category: 'fruit'}, {catid: 1, name: 'banana', category: 'fruit'}]; const groupMap = new Map(); for (const item of arr1) { const key = item.catid; // 初始化当前catid对应的数组(如果不存在) if (!groupMap.has(key)) { groupMap.set(key, []); } // 将当前元素推入对应分组 groupMap.get(key).push(item); } // 转换为二维数组 const arr2 = Array.from(groupMap.values()); console.log(arr2);
TypeScript版本实现
如果使用TypeScript,只需要添加类型定义,确保类型安全:
// 定义数组元素的类型 interface Item { catid: number; name: string; category: string; } const arr1: Item[] = [{catid: 1, name: 'mango', category: 'fruit'}, {catid: 2, name: 'potato', category: 'veg'}, {catid: 3, name: 'chiken', category: 'nonveg'},{catid: 1, name: 'apple', category: 'fruit'}, {catid: 1, name: 'banana', category: 'fruit'}]; // Reduce方式 const groupedObj = arr1.reduce<Record<number, Item[]>>((acc, item) => { if (!acc[item.catid]) { acc[item.catid] = []; } acc[item.catid].push(item); return acc; }, {}); const arr2: Item[][] = Object.values(groupedObj); // Map方式 const groupMap = new Map<number, Item[]>(); for (const item of arr1) { const key = item.catid; if (!groupMap.has(key)) { groupMap.set(key, []); } groupMap.get(key)?.push(item); } const arr2FromMap: Item[][] = Array.from(groupMap.values());
上述两种方式都能得到符合需求的二维数组,且会保留原数组中各组元素的出现顺序(ES6及以上环境中,Object.values和Map均会保留键的插入顺序)。
内容的提问来源于stack exchange,提问作者Rajesh Kumar
相关产品推荐
相关产品推荐

