Ramda GroupBy - 如何按任何道具分组
Ramda GroupBy - How to group by any prop
给定:
interface Dict {
[key: string]: any
}
const data: Dict[] = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
未指定这些 Dict
对象的键...
我怎样才能得到这个结果?
const result = {
id: ['a', 'b', 'c', 'd', 'e'],
b: ['something', 'else'],
extra: ['hello world'],
// ... and any other possible key
}
使用 R.reduce 和 R.mergeWith 并连接所有项目:
const { mergeWith, reduce } = R
const fn = reduce(mergeWith((a, b) => [].concat(a, b)), {})
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
如果您还需要数组中的单个值 (extra
),请映射项目,并用数组包装,只是已经不是数组的值:
const { pipe, mergeWith, reduce, map, unless, is, of } = R
const fn = pipe(
reduce(mergeWith((a, b) => [].concat(a, b)), {}),
map(unless(is(Array), of))
)
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
您可以将对象展平成对列表,将其分组,然后将对转换回值:
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
let z = R.pipe(
R.chain(R.toPairs),
R.groupBy(R.head),
R.map(R.map(R.last))
)
console.log(z(data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
与 Ori Drori 的回答略有不同:
(假设您的对象中的任何属性都已包含在数组中)
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' }
];
const run = reduce(useWith(mergeWith(concat), [identity, map(of)]), {});
console.log(
run(data)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {reduce, useWith, mergeWith, concat, identity, map, of} = R;</script>
给定:
interface Dict {
[key: string]: any
}
const data: Dict[] = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
未指定这些 Dict
对象的键...
我怎样才能得到这个结果?
const result = {
id: ['a', 'b', 'c', 'd', 'e'],
b: ['something', 'else'],
extra: ['hello world'],
// ... and any other possible key
}
使用 R.reduce 和 R.mergeWith 并连接所有项目:
const { mergeWith, reduce } = R
const fn = reduce(mergeWith((a, b) => [].concat(a, b)), {})
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
如果您还需要数组中的单个值 (extra
),请映射项目,并用数组包装,只是已经不是数组的值:
const { pipe, mergeWith, reduce, map, unless, is, of } = R
const fn = pipe(
reduce(mergeWith((a, b) => [].concat(a, b)), {}),
map(unless(is(Array), of))
)
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
您可以将对象展平成对列表,将其分组,然后将对转换回值:
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
let z = R.pipe(
R.chain(R.toPairs),
R.groupBy(R.head),
R.map(R.map(R.last))
)
console.log(z(data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
与 Ori Drori 的回答略有不同: (假设您的对象中的任何属性都已包含在数组中)
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' }
];
const run = reduce(useWith(mergeWith(concat), [identity, map(of)]), {});
console.log(
run(data)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {reduce, useWith, mergeWith, concat, identity, map, of} = R;</script>