功能组成
compose
从右向左
/*
* 1. take x
* 2. execute g(x)
* 3. take the return value of g(x) and execute f with it
*/
const compose = (f, g) => x => f(g(x))
还有一个函数叫做
pipe
评估依据
const pipe = (g, f) => x => f(g(x))
您的代码
正如已经提到的
@Nima Hakimi
,您已反转参数顺序。
-
切换参数的顺序
const ungroupAndFlatten = compose(
flatten,
ungroup
)
const compose = (f, g) => x =>
f(g(x))
const ungroup = obj =>
Object.keys(obj)
.map(x => obj[x]);
const flatten = arrs =>
arrs.reduce((acc, item) => acc.concat(item), [])
const groupedByName = {
abc: [
{ name: 'abc', effectiveDate: '2016-01-01T00:00:00+00:00' },
{ name: 'abc', effectiveDate: '2016-04-01T00:00:00+00:00' },
{ name: 'abc', effectiveDate: '2016-05-01T00:00:00+00:00' }
],
abcd: [
{ name: 'abcd', effectiveDate: '2016-02-01T00:00:00+00:00' },
{ name: 'abcd', effectiveDate: '2016-09-01T00:00:00+00:00' }
]
}
const ungroupAndFlatten = compose(
flatten,
ungroup
)
console.log(
ungroupAndFlatten(groupedByName)
)
-
const ungroupAndFlatten = pipe(
ungroup,
flatten
)
const pipe = (g, f) => x =>
f(g(x))
const ungroup = obj =>
Object.keys(obj)
.map(x => obj[x]);
const flatten = arrs =>
arrs.reduce((acc, item) => acc.concat(item), [])
const groupedByName = {
abc: [
{ name: 'abc', effectiveDate: '2016-01-01T00:00:00+00:00' },
{ name: 'abc', effectiveDate: '2016-04-01T00:00:00+00:00' },
{ name: 'abc', effectiveDate: '2016-05-01T00:00:00+00:00' }
],
abcd: [
{ name: 'abcd', effectiveDate: '2016-02-01T00:00:00+00:00' },
{ name: 'abcd', effectiveDate: '2016-09-01T00:00:00+00:00' }
]
}
const ungroupAndFlatten = pipe(
ungroup,
flatten
)
console.log(
ungroupAndFlatten(groupedByName)
)
功能组合
n
论据
-
组成
const compose = (...fns) => fns.reduceRight((f, g) => (...args) =>
g(f(...args)))
-
const pipe = (...fns) => fns.reduce((f, g) => (...args) =>
g(f(...args)))
我们的目标是
ungroup
flatten
groupBy
也
const groupByNameAndFlattenAndUngroup = compose(
flatten,
ungroup,
groupBy('name', x) // <-- this is our problem
)
但这行不通。我们只能用一个参数组合函数。解决方法是重写
到a
咖喱
const groupBy = xs => key =>
xs.reduce((rv, x) => {
(rv[x[key]] = rv[x[key]] || []).push(x)
return rv
}, {})
const groupByNameAndFlattenAndUngroup = (key, xs) => compose(
flatten,
ungroup,
groupBy ('name')
) (xs)
但这个解决方案可以更短。如果我们把参数的顺序从
groupBy公司
到
groupBy = key => xs => {/*..*/}
我们可以做到:
const groupBy = key => xs =>
xs.reduce((rv, x) => {
(rv[x[key]] = rv[x[key]] || []).push(x)
return rv
}, {})
const groupByNameAndFlattenAndUngroup = compose(
flatten,
ungroup,
groupBy ('name')
)
工作示例
const arrs = [
{name: 'abc', effectiveDate: "2016-01-01T00:00:00+00:00"},
{name: 'abcd', effectiveDate: "2016-02-01T00:00:00+00:00"},
{name: 'abcd', effectiveDate: "2016-09-01T00:00:00+00:00"},
{name: 'abc', effectiveDate: "2016-04-01T00:00:00+00:00"},
{name: 'abc', effectiveDate: "2016-05-01T00:00:00+00:00"},
]
const compose = (...fns) => fns.reduceRight((f, g) => (...args) =>
g(f(...args)))
const ungroup = obj =>
Object.keys(obj)
.map(x => obj[x]);
const flatten = arrs =>
arrs.reduce((acc, item) => acc.concat(item), [])
const groupBy = key => xs =>
xs.reduce((rv, x) => {
(rv[x[key]] = rv[x[key]] || []).push(x)
return rv
}, {})
const groupByName = groupBy ('name')
const groupByEffectiveDate = groupBy ('effectiveDate')
const groupByNameAndFlattenAndUngroup = compose(
flatten,
ungroup,
groupByName
)
const groupBygroupByEffectiveDateAndFlattenAndUngroup = compose(
flatten,
ungroup,
groupByEffectiveDate
)
console.log(
groupByNameAndFlattenAndUngroup (arrs)
)
console.log(
groupBygroupByEffectiveDateAndFlattenAndUngroup (arrs)
)