使用 ramda 过滤掉唯一的嵌套值
Filter out unique nested values using ramda
我有一组 UNIX 时间戳,如下所示:
[
{"start_time":1540458000000, "end_time":1540472400000},
{"start_time":1540458000000, "end_time":1540486800000},
{"start_time":1540458000000, "end_time":1540501200000},
{"start_time":1540472400000, "end_time":1540486800000},
{"start_time":1540472400000, "end_time":1540501200000},
{"start_time":1540486800000, "end_time":1540501200000}
]
我想从 start_time
和 end_time
中挑选出所有唯一值,所以我剩下:
[
{"start_time":1540458000000},
{"start_time":1540472400000},
{"start_time":1540486800000}
{"end_time":1540472400000},
{"end_time":1540486800000},
{"end_time":1540501200000},
]
我已经研究过使用类似的方法使用 groupBy
、pluck
、zipObj
以及更多使用 的方法。但不幸的是没有运气。
无需指定特定键即可工作的 ramda 函数是锦上添花。
不确定 ramda,但下面的普通 js 函数可以做到这一点
const arr = [
{"start_time":1540458000000, "end_time":1540472400000},
{"start_time":1540458000000, "end_time":1540486800000},
{"start_time":1540458000000, "end_time":1540501200000},
{"start_time":1540472400000, "end_time":1540486800000},
{"start_time":1540472400000, "end_time":1540501200000},
{"start_time":1540486800000, "end_time":1540501200000}
];
function foo(arr) {
return [...arr.reduce((a, b) => {
Object.entries(b).forEach(e => a.set(String(e), e));
return a;
}, new Map())].map(([_,e]) => ({
[e[0]]: e[1]
}))
}
console.log(foo(arr));
如果你想要的属性未知,但出现在所有对象中,你可以将每个对象转换成对,转置结果数组,获取每个数组的唯一值,将它们解嵌为一个数组,然后转换返回对象:
const { pipe, map, toPairs, transpose, uniqBy, last, unnest, objOf, apply } = R;
const data = [
{"start_time":1540458000000, "end_time":1540472400000},
{"start_time":1540458000000, "end_time":1540486800000},
{"start_time":1540458000000, "end_time":1540501200000},
{"start_time":1540472400000, "end_time":1540486800000},
{"start_time":1540472400000, "end_time":1540501200000},
{"start_time":1540486800000, "end_time":1540501200000}
];
const getUniqueProps =
pipe(
map(toPairs),
transpose,
map(uniqBy(last)),
unnest,
map(apply(objOf))
);
console.log(getUniqueProps(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
如果你知道你想要的属性,你可以groupBy
一个属性,从每个组中获取第一个对象,然后从每个对象中选择你想要的属性:
const { groupBy, prop, concat, pipe, map, head, pick, values } = R;
const data = [
{"start_time":1540458000000, "end_time":1540472400000},
{"start_time":1540458000000, "end_time":1540486800000},
{"start_time":1540458000000, "end_time":1540501200000},
{"start_time":1540472400000, "end_time":1540486800000},
{"start_time":1540472400000, "end_time":1540501200000},
{"start_time":1540486800000, "end_time":1540501200000}
];
const getUniqueProp = (propName) =>
pipe(
groupBy(prop(propName)),
map(pipe(head, pick([propName]))),
values,
);
const getStartEnd = (data) => concat(
getUniqueProp('start_time')(data),
getUniqueProp('end_time')(data),
);
console.log(getStartEnd(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
另一种 Ramda 方法:
const {pipe, map, toPairs, unnest, groupBy, head, uniqBy, last, values, apply, objOf} = R
const uniqTimes = pipe(
map(toPairs), //=> [[['start', 1], ['end', 2]], [['start', 1], ['end', 3]], ...]
unnest, //=> [['start', 1], ['end', 2], ['start', 1], ['end', 3], ...]
groupBy(head), //=> {start: [['start', 1], ['start', 1], ['start', 4], ...], end: [['end', 2], ...]}
map(uniqBy(last)), //=> {start: [['start', 1], ['start', 4], ...], end: [['end', 2], ...]}
values, //=> [[['start', 1], ['start', 4], ...], [['end', 2], ...]]
unnest, //=> [['start', 1], ['start', 4], ..., ['end', 2], ...]
map(apply(objOf)) //=> [{"start": 1}, {"start": 4}, ..., {"end": 2}, ...]
)
const timestamps = [{"start_time":1540458000000,"end_time":1540472400000},{"start_time":1540458000000,"end_time":1540486800000},{"start_time":1540458000000,"end_time":1540501200000},{"start_time":1540472400000,"end_time":1540486800000},{"start_time":1540472400000,"end_time":1540501200000},{"start_time":1540486800000,"end_time":1540501200000}]
console.log(uniqTimes(timestamps))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
这就是我喜欢使用 Ramda 的方式:构建一个函数管道,每个函数都进行简单的转换。
更新
有评论询问如何生成更像
的输出
{
"start_time": [1540458000000, 1540458000000],
"end_time": [1540472400000, 1540486800000]
}
对于相同的输入应该这样做:
const uniqTimes = pipe(
map(toPairs),
unnest,
groupBy(head),
map(map(last)),
map(uniq)
)
我有一组 UNIX 时间戳,如下所示:
[
{"start_time":1540458000000, "end_time":1540472400000},
{"start_time":1540458000000, "end_time":1540486800000},
{"start_time":1540458000000, "end_time":1540501200000},
{"start_time":1540472400000, "end_time":1540486800000},
{"start_time":1540472400000, "end_time":1540501200000},
{"start_time":1540486800000, "end_time":1540501200000}
]
我想从 start_time
和 end_time
中挑选出所有唯一值,所以我剩下:
[
{"start_time":1540458000000},
{"start_time":1540472400000},
{"start_time":1540486800000}
{"end_time":1540472400000},
{"end_time":1540486800000},
{"end_time":1540501200000},
]
我已经研究过使用类似的方法使用 groupBy
、pluck
、zipObj
以及更多使用
无需指定特定键即可工作的 ramda 函数是锦上添花。
不确定 ramda,但下面的普通 js 函数可以做到这一点
const arr = [
{"start_time":1540458000000, "end_time":1540472400000},
{"start_time":1540458000000, "end_time":1540486800000},
{"start_time":1540458000000, "end_time":1540501200000},
{"start_time":1540472400000, "end_time":1540486800000},
{"start_time":1540472400000, "end_time":1540501200000},
{"start_time":1540486800000, "end_time":1540501200000}
];
function foo(arr) {
return [...arr.reduce((a, b) => {
Object.entries(b).forEach(e => a.set(String(e), e));
return a;
}, new Map())].map(([_,e]) => ({
[e[0]]: e[1]
}))
}
console.log(foo(arr));
如果你想要的属性未知,但出现在所有对象中,你可以将每个对象转换成对,转置结果数组,获取每个数组的唯一值,将它们解嵌为一个数组,然后转换返回对象:
const { pipe, map, toPairs, transpose, uniqBy, last, unnest, objOf, apply } = R;
const data = [
{"start_time":1540458000000, "end_time":1540472400000},
{"start_time":1540458000000, "end_time":1540486800000},
{"start_time":1540458000000, "end_time":1540501200000},
{"start_time":1540472400000, "end_time":1540486800000},
{"start_time":1540472400000, "end_time":1540501200000},
{"start_time":1540486800000, "end_time":1540501200000}
];
const getUniqueProps =
pipe(
map(toPairs),
transpose,
map(uniqBy(last)),
unnest,
map(apply(objOf))
);
console.log(getUniqueProps(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
如果你知道你想要的属性,你可以groupBy
一个属性,从每个组中获取第一个对象,然后从每个对象中选择你想要的属性:
const { groupBy, prop, concat, pipe, map, head, pick, values } = R;
const data = [
{"start_time":1540458000000, "end_time":1540472400000},
{"start_time":1540458000000, "end_time":1540486800000},
{"start_time":1540458000000, "end_time":1540501200000},
{"start_time":1540472400000, "end_time":1540486800000},
{"start_time":1540472400000, "end_time":1540501200000},
{"start_time":1540486800000, "end_time":1540501200000}
];
const getUniqueProp = (propName) =>
pipe(
groupBy(prop(propName)),
map(pipe(head, pick([propName]))),
values,
);
const getStartEnd = (data) => concat(
getUniqueProp('start_time')(data),
getUniqueProp('end_time')(data),
);
console.log(getStartEnd(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
另一种 Ramda 方法:
const {pipe, map, toPairs, unnest, groupBy, head, uniqBy, last, values, apply, objOf} = R
const uniqTimes = pipe(
map(toPairs), //=> [[['start', 1], ['end', 2]], [['start', 1], ['end', 3]], ...]
unnest, //=> [['start', 1], ['end', 2], ['start', 1], ['end', 3], ...]
groupBy(head), //=> {start: [['start', 1], ['start', 1], ['start', 4], ...], end: [['end', 2], ...]}
map(uniqBy(last)), //=> {start: [['start', 1], ['start', 4], ...], end: [['end', 2], ...]}
values, //=> [[['start', 1], ['start', 4], ...], [['end', 2], ...]]
unnest, //=> [['start', 1], ['start', 4], ..., ['end', 2], ...]
map(apply(objOf)) //=> [{"start": 1}, {"start": 4}, ..., {"end": 2}, ...]
)
const timestamps = [{"start_time":1540458000000,"end_time":1540472400000},{"start_time":1540458000000,"end_time":1540486800000},{"start_time":1540458000000,"end_time":1540501200000},{"start_time":1540472400000,"end_time":1540486800000},{"start_time":1540472400000,"end_time":1540501200000},{"start_time":1540486800000,"end_time":1540501200000}]
console.log(uniqTimes(timestamps))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
这就是我喜欢使用 Ramda 的方式:构建一个函数管道,每个函数都进行简单的转换。
更新
有评论询问如何生成更像
的输出{
"start_time": [1540458000000, 1540458000000],
"end_time": [1540472400000, 1540486800000]
}
对于相同的输入应该这样做:
const uniqTimes = pipe(
map(toPairs),
unnest,
groupBy(head),
map(map(last)),
map(uniq)
)