我有这个对象数组:
[
{ name: 'foo1', speed: 8 },
{ name: 'foo2', speed: 7 },
{ name: 'foo3', speed: 10 },
{ name: 'foo4', speed: 12 },
{ name: 'foo5', speed: 8 },
{ name: 'foo6', speed: 5 }
]
现在,我想基于“ speed”属性将数组元素分组为块。如果当前,下一个和上一个元素的速度小于等于10,则应将这些元素分组在一起。如果发生其他情况,则将创建另一个组,该组将收集具有speed属性> 10的元素。
最后,我想要一个由3个数组组成的数组:
[
[
{ name: 'foo1', speed: 8 },
{ name: 'foo2', speed: 7 },
{ name: 'foo3', speed: 10 }
], [
{ name: 'foo4', speed: 12 }
], [
{ name: 'foo5', speed: 8 },
{ name: 'foo6', speed: 5 }
]
]
重要的是要保持元素的顺序,只是将它们分组。基本数组的长度可以变化,因此必须动态计算所有内容。我曾尝试使用一些loadash方法,但没有任何真正的解决方案。
答案 0 :(得分:2)
如果要按阈值分组,应使用>
而不是>=
。
只需减少项目,然后使用异或逻辑检查即可。
const data = [
{ name: 'foo1', speed: 8 },
{ name: 'foo2', speed: 7 },
{ name: 'foo3', speed: 10 },
{ name: 'foo4', speed: 12 },
{ name: 'foo5', speed: 8 },
{ name: 'foo6', speed: 5 }
];
const groupDataByThreshold = ([ head, ...rest ], key, threshold) =>
rest.reduce((result, item) => {
const prevGroup = result[result.length - 1],
prevItem = prevGroup[prevGroup.length - 1],
prevOver = prevItem[key] > threshold,
currOver = item[key] > threshold;
if ((currOver && prevOver) || (!currOver && !prevOver)) {
prevGroup.push(item);
} else {
result.push([ item ]);
}
return result;
}, [ [ head ] ])
const grouped = groupDataByThreshold(data, 'speed', 10);
console.log(grouped);
.as-console-wrapper { top: 0; max-height: 100% !important; }
答案 1 :(得分:0)
您可以使用reduce
方法执行此操作,方法是在每次迭代中检查最后添加的元素是<= 10
,当前元素是> 10
还是反向元素,如果是,则添加新数组。
const data = [
{ name: 'foo1', speed: 8 },
{ name: 'foo2', speed: 7 },
{ name: 'foo3', speed: 10 },
{ name: 'foo4', speed: 12 },
{ name: 'foo5', speed: 8 },
{ name: 'foo6', speed: 5 }
]
const result = data.reduce((r, e, i, a) => {
const last = a[i - 1]
if (!last || last.speed <= 10 && e.speed > 10 || last.speed > 10 && e.speed <= 10) {
r.push([e])
} else {
r[r.length - 1].push(e)
}
return r;
}, []);
console.log(result)