基于角度与距离双条件,用Angular JS reduce实现数组自定义分组
解决方案:角度+距离双条件数组分组
要实现你的双条件分组需求,可以分两步完成:先按角度完成初次分组,再对每个角度组按距离进行二次拆分。具体代码如下:
const filteredItems = [ { id: "1", distance: 220, angle: 60}, { id: "2", distance: 320, angle: 65}, { id: "3", distance: 20, angle: 64}, { id: "4", distance: 25, angle: 63}, { id: "5", distance: 30, angle: 7}, { id: "6", distance: 500, angle: 62}, { id: "7", distance: 145, angle: 20}, { id: "8", distance: 120, angle: 22}, { id: "9", distance: 190, angle: -126}, { id: "10", distance: 90, angle: -122} ]; // 1. 按角度排序,确保角度相近的元素聚集 filteredItems.sort((a, b) => a.angle - b.angle); const angleGroupDelta = 4; // 角度分组阈值 const distanceGroupDelta = 120; // 距离分组阈值 // 2. 按角度差<=4完成初次分组 let angleGrouped = filteredItems.reduce((prev, curr, idx, ary) => { if (!idx || Math.abs(ary[idx - 1].angle - curr.angle) > angleGroupDelta) { prev.push([]); } prev[prev.length - 1].push(curr); return prev; }, []); // 3. 对每个角度组按距离排序后,再按距离差>120拆分 let finalGrouped = angleGrouped.flatMap(group => { // 先对当前角度组的元素按距离排序 const sortedByDistance = [...group].sort((a, b) => a.distance - b.distance); // 对排序后的数组按距离差拆分 return sortedByDistance.reduce((prev, curr, idx, ary) => { if (!idx) { prev.push([curr]); } else { // 取当前子组的第一个元素(排序后距离最小的)和当前元素比差值 const firstInSubGroup = prev[prev.length - 1][0]; if (Math.abs(curr.distance - firstInSubGroup.distance) > distanceGroupDelta) { prev.push([curr]); } else { prev[prev.length - 1].push(curr); } } return prev; }, []); }); // 输出结果与预期一致 console.log(JSON.stringify(finalGrouped, null, 2));
关键逻辑说明
- 角度排序与分组:沿用你已实现的逻辑,先按角度排序,再用
reduce把角度差<=4的元素归为一组。 - 距离二次分组:
- 对每个角度组先按
distance排序,确保距离有序后才能准确判断差值。 - 再次用
reduce遍历排序后的数组:如果当前元素和当前子组第一个元素的距离差>120,就新建一个子组;否则加入当前子组。这样能保证同一个子组内所有元素的距离差都<=120。
- 对每个角度组先按
- 平铺结果:用
flatMap把嵌套的子组平铺成最终的二维数组,直接得到你需要的结构。
内容的提问来源于stack exchange,提问作者bob parr
相关产品推荐
相关产品推荐

