JavaScript数组的几种常见使用场景(不定时更新)

📅 发布时间:2026/7/30 17:14:02
JavaScript数组的几种常见使用场景(不定时更新) 一、数组去重对象数组合并和去重https://blog.csdn.net/qq_42750608/article/details/133362686?spm1011.2415.3001.5331利用集合的特性给数组去重https://blog.csdn.net/qq_42750608/article/details/84036896?spm1011.2415.3001.5331二、数组分组:含义: 数据按照某个特性归类1. reducefn(cur, index)作为对象的key,值为按照fn筛选出来的数据// 利用reduce分组 function group(arr, fn) { // 不是数组 if (!Array.isArray(arr)) { return arr } // 不是函数 if (typeof fn ! function) { throw new TypeError(fn必须是一个函数) } var v return arr.reduce((obj, cur, index) { v fn(cur, index) if (!Reflect.hasOwnProperty.call(obj, v)) { obj[v] [] } obj[v].push(cur) return obj }, {}) } // 按照字符串长度分组 let products [apple, pear, orange, peach]; const f1 v v.length console.log( group(products, f1), ); // 按照分数分组 result [{ name: tom, score: 60 }, { name: Jim, score: 40 }, { name: Nick, score: 88 }] const fn v v.score 60 console.log( group(result, fn), );2.filterfn(value, index)作为对象的key,值为按照fn筛选出来的数据// 利用forEach和filter分组 function group(arr, fn) { // 不是数组 if (!Array.isArray(arr)) { return arr } // 不是函数 if (typeof fn ! function) { throw new TypeError(fn必须是一个函数) } let obj {} arr.forEach((item, key) { const v fn(item, key) obj[v] arr.filter((ee, ix) fn(ee, ix) v) }); return obj } // 按照字符串长度分组 let products [apple, pear, orange, peach]; const f1 v v.length console.log( group(products, f1), ); // 按照分数分组 result [{ name: tom, score: 60 }, { name: Jim, score: 40 }, { name: Nick, score: 88 }] const fn v v.score 60 console.log( group(result, fn), );3.Map分组使用场景比如antd的Table组件需要的数组数据格式化为可合并单元格的数据egconst columns [{title: 姓名,dataIndex: name,onCell: (_, index) ({ rowSpan: record.auditResultRowSpan || 0 }),},{ title: 年龄, dataIndex: age },]核心规则┌───────────────────────────────────────────────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────┐│值 │含义 │├───────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤│rowSpan: n │当前单元格向下占 n 行 │├───────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤│rowSpan: 0 │当前单元格被合并掉不渲染 │├───────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤│colSpan: n │当前单元格向右占 n 列 │├───────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤│colSpan: 0 │当前单元格被合并掉不渲染 │└───────────────────────────────────────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────┘forEach map values flatMap sort const getGroupList (details []) { if (!isArrMoreThanZero(details)) return []; // 分组 const groups new Map(); details.forEach((item, index) { const isAiAudit 分组的体检略。。。; const groupKey isAiAudit ? __AI_AUDIT__ : index; if (!groups.has(groupKey)) groups.set(groupKey, []); groups.get(groupKey).push({ ...item, index, auditResultRowSpan: 0 }); }); // 计算 rowSpan 扁平化 最后统一排序一次 return Array.from(groups.values()) .flatMap(group group.map((val, idx) ({ ...val, auditResultRowSpan: idx 0 ? group.length : 0, })) ) .sort((a, b) a.index - b.index); };reduce 对象 Object.values flatMap sort const getGroupList (details []) { if (!isArrMoreThanZero(details)) return []; // 分组 const objFilter details.reduce((acc, item, index) { item.auditResultRowSpan 0; const auditResultGroupKey 分组条件略。。。 || index; if (!acc[auditResultGroupKey]) { acc[auditResultGroupKey] [{ ...item, index }]; } else { acc[auditResultGroupKey].push({ ...item, index }); } return acc; }, {}); // 计算 rowSpan 扁平化 最后统一排序一次 return Array.from(Object.values(objFilter)) .flatMap(group group.map((val, idx) ({ ...val, auditResultRowSpan: idx 0 ? group.length : 0, })) ) .sort((a, b) a.index - b.index); };4.for循环const getGroupList (details []) { if (!isArrMoreThanZero(details)) return []; const FILE_TYPE_ARR [a, b, c]; // 要求可以合并的文件类型 const INDEX_ARR [0, 1, 2]; // 要求可以合并的表格行的下标 const n details.length; const limit Math.min(INDEX_ARR.length, n); // 先统计 AI 组 大小仅前 3 项可能是 AI 组成员 let aiCount 0; for (let i 0; i limit; i) { if (AI_ATTCHMENT_TYPE_ARR.includes(details[i].fileType)) aiCount; } // 一次遍历保 持原顺序直接算 rowSpan let aiSeen 0; const result new Array(n); for (let i 0; i n; i) { const inAiGroup i limit FILE_TYPE_ARR.includes(details[i].fileType); let rowSpan; if (inAiGroup) { rowSpan aiSeen 0 ? aiCount : 0; // 组内首项组大小其余0 aiSeen; } else { rowSpan 1; // 单元素组 } result[i] { ...details[i], index: i, auditResultRowSpan: rowSpan }; } return result; };最核心优点虽然for循环写代码看起来不高级但用好了将是优化性能的利器之一。其他优点分析原版reduce 对象 Object.values flatMap sort优化版for时间复杂度O(n log n)O(n)对象拷贝项2次1次临时结构顺序sort天然就是升序排序三、快捷创建数组批量快捷创建新数组的几种方式https://blog.csdn.net/qq_42750608/article/details/133363498?spm1011.2415.3001.5331四、数组排序前端对普通数字数组排序示例https://blog.csdn.net/qq_42750608/article/details/134019466?spm1011.2415.3001.5331五、返回两个数组之间的差异数组 a 上过滤出数组 b 中不包含的值https://blog.csdn.net/qq_42750608/article/details/115354638?spm1011.2415.3001.5331六、求数组的交集和差集求数组的交集和差集https://blog.csdn.net/qq_42750608/article/details/133384167?spm1011.2415.3001.5331七、树形对象数组1.带children的树形对象数组筛选后显示import { get } from lodash-es const isArrMoreThanOneLength val Array.isArray(val) val.length 0 const getFilterTreeOptions (arr) { return filter(JSON.parse(JSON.stringify(arr)), (item) { if (String(item.status) 0) { // 筛选条件 return showFlag.value } if (isArrMoreThanOneLength(get(item, children))) { item.children fn(item.children) return Array.isArray(fn(item.children)) } return true }) } // 使用 const arr1 getFilterTreeOptions([某树形对象数组...略...])2.带children的树形对象数组添加其他属性给树形对象数组添加key、全称、层级属性import { each, get } from lodash-es const handleFuncInArray (arr, cb) { each(arr, (item) { cb(item) if (isArrMoreThanOneLength(get(item, children))) { handleFuncInArray(item.children, cb) } }) } const getListAndDicts (treeList) { const dicts {} handleFuncInArray(treeList, (item) { item.key item.orgCode item.fullLabel item.fullLabel || item.label item.levelNum item.levelNum || 0 if (isArrMoreThanOneLength(get(item, children))) { for (const ee of item.children) { ee.fullLabel item.fullLabel - (ee.label|| ) ee.levelNum item.levelNum 1 } } const obj omit(item, children) dicts[item.key] obj }) return { treeList, dicts } } // 使用 const { treeList, dicts } getListAndDicts([某树形对象数组...略...])