基于嵌套数组文本分组对象数组:使用reduce重构函数
用reduce重构分组函数是否更优?
我有一个接受三个参数的函数:数据数组、key和部分匹配值。我希望根据每个对象嵌套数组中可能存在的值对结果进行分组。目前我的代码可以正常运行,但想了解是否使用reduce重构会更优。
示例数据数组
const arr = [ { "id": "vghjnbghjkoijhjnmkjhjk", "region": "US", "tags": ["tag1:bvghjhgh","tag2:bvghjkjnm","tag3:vghjbghj"] }, { "id": "cvbhyt56789-mnbvghyu76", "region": "US", "tags": ["tag1:bvghjhgh"] }, { "id": "ghjkjnbhjnbhjkmnhjkmjk", "region": "US", "tags": ["tag2:bvghjkjnm"] }, { "id": "ghjkjnbhjnbhjkmnhjkmjk", "region": "US", "tags": [] }, { "id": "bghjkjnbghjkjnhjnbhjhj", "region": "CA", "tags": ["tag1:bvghjhgh","tag3:vghjbghj"] } ];
预期结果
当key为tags、value为tag1时,返回结果如下:
[ [ { "id": "vghjnbghjkoijhjnmkjhjk", "region": "US", "tags": ["tag1:bvghjhgh","tag2:bvghjkjnm","tag3:vghjbghj"] }, { "id": "cvbhyt56789-mnbvghyu76", "region": "US", "tags": ["tag1:bvghjhgh"] }, { "id": "bghjkjnbghjkjnhjnbhjhj", "region": "CA", "tags": ["tag1:bvghjhgh","tag3:vghjbghj"] } ], [ { "id": "ghjkjnbhjnbhjkmnhjkmjk", "region": "US", "tags": ["tag2:bvghjkjnm"] }, { "id": "ghjkjnbhjnbhjkmnhjkmjk", "region": "US", "tags": [] }, ] ]
当前实现代码
function groupData(arr, key, value) { const grouped = {}; const remaining = []; for (const obj of arr) { const index = obj[key].findIndex(elem => elem.includes(value)); if (index > -1) { const groupByKey = obj[key][index]; if (grouped.hasOwnProperty(groupByKey)) { grouped[groupByKey].push(obj); } else { grouped[groupByKey] = [obj]; } } else { remaining.push(obj); } } return [Object.values(grouped).flat(), remaining]; // 注:原代码里的noMatch应为remaining,此处修正笔误 }
用reduce重构的版本
可以用Array.reduce()把逻辑整合到一个函数调用里,实现更紧凑的函数式风格:
function groupDataWithReduce(arr, key, value) { const { grouped, remaining } = arr.reduce((acc, obj) => { const matchingTag = obj[key].find(elem => elem.includes(value)); if (matchingTag) { acc.grouped[matchingTag] = [...(acc.grouped[matchingTag] || []), obj]; } else { acc.remaining.push(obj); } return acc; }, { grouped: {}, remaining: [] }); return [Object.values(grouped).flat(), remaining]; }
两种实现的对比
- 可读性:原for循环逻辑直白,新手更容易理解和调试;reduce版本更紧凑,但需要熟悉函数式编程风格才能快速理清逻辑。
- 性能:两者都是O(n)时间复杂度(n为数组长度),每个元素仅遍历一次,性能差异可忽略。
- 灵活性:reduce把状态管理整合到一个对象中,后续扩展分组规则时修改更方便;for循环则需要维护外部变量。
如果你偏好函数式编程风格、追求代码简洁,reduce重构是不错的选择;如果团队新手较多、需要更直观的调试体验,原有for循环写法也完全没问题——两种方式都能达到预期效果,没有绝对的“更优”,取决于你的场景和团队习惯。
内容的提问来源于stack exchange,提问作者johnny_mac
相关产品推荐
相关产品推荐

