如果我们有一个列表,例如:
[
{
type: 'a',
},
{
type: 'a',
},
{
type: 'b',
},
{
type: 'a',
}
]
...,我们想对其进行分段以创建一个列表,以便新列表由初始列表的每个片段组成,此处按类型划分,如下所示:
[
[
{
type: 'a',
},
{
type: 'a',
},
],
[
{
type: 'b',
},
],
[
{
type: 'a',
}
]
]
我想创建一个通用的“细分”功能,该功能需要比较两个项目并确定是否需要一个新细分的功能。在这里,该函数的“细分器”只是比较类型。
我可以用普通的javascript语言编写,但是有一种用Ramda做到这一点的好方法吗?
const data = [
{
type: 'a',
},
{
type: 'a',
},
{
type: 'b',
},
{
type: 'a',
}
];
const segmentBy = segmenter => items => {
const segmentReducer = (prev = [], curr) => {
let lastSegment = [];
let lastItem = null;
try {
lastSegment = prev[prev.length - 1];
lastItem = lastSegment[lastSegment.length - 1];
} catch (e) {
return [...prev, [curr]];
}
const requiresNewSegment = segmenter(lastItem, curr);
if (requiresNewSegment) {
return [...prev, [curr]];
}
return [...prev.slice(0, prev.length - 1), [...lastSegment, curr]];
};
return items.reduce(segmentReducer, []);
};
const segmentByType = segmentBy((a, b) => a.type !== b.type);
const segments = segmentByType(data);
console.dir(segments);
答案 0 :(得分:3)
使用Ramda可以使用R.groupWith:
获取列表并返回列表列表,其中每个子列表的元素 根据提供的内容均满足成对比较 功能。仅将相邻元素传递给比较 功能。
const data = [{"type":"a"},{"type":"a"},{"type":"b"},{"type":"a"}];
const segmentByType = R.groupWith(R.eqBy(R.prop('type')));
const segments = segmentByType(data);
console.dir(segments);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
在香草中,主要问题是何时向累加器添加新的子数组。当它是第一项或segmenter
返回true
时,您需要添加另一个子数组。
const data = [{"type":"a"},{"type":"a"},{"type":"b"},{"type":"a"}];
const segmentBy = segmenter => items =>
items.reduce((r, item, i, arr) => {
if(i === 0 || segmenter(item, arr[i - 1])) r.push([]);
r[r.length - 1].push(item);
return r;
}, []);
const segmentByType = segmentBy((a, b) => a.type !== b.type);
const segments = segmentByType(data);
console.dir(segments);