如果我有一个数组public class ImagePojo {
public Map<String, String> map;
public ImagePojo(Map<String, String> map) {
this.map = map;
}
}
,我首先想要进行一些操作,然后将该结果传递给一个以数组作为参数的函数someArray
。如下所示
arrfun
在上面的场景中,我想避免分配一个中间变量来传递给let arr = someArray.filter(foo).map(bar)
let result = arrfun(arr)
。我希望有这样的东西。
arrfun
Object.prototype.pipe = function(f) {return f(this)}
let result = someArray.filter(foo).map(bar).pipe(arrfun)
你会如何解决这个问题?.pipe()
?Object
是这个功能的最佳名称吗? pipe
? chain
?新示例
pass
在上面的示例中,问题是const pc = options => options
.join(' ')
.match(/--[\w.]* [\w.]*/g)
.map(s => s.slice(2).split(' '))
.map(([key, value]) => ({key, value}))
.map(nestObject)
.reduce((acc, val) => Object.assign(acc, val), {})
const nestObject = ({key, value}) => key
.split('.')
.reverse()
.reduce((inner, key) => ({[key]: inner}), value)
如果找不到匹配则返回.match
。使用null
即可将其更改为
.pipe
如果没有.pipe(s => s.match(/--[\w.]* [\w.]*/g) || [])
,您将如何解决这个问题?
答案 0 :(得分:2)
在上面的场景中,我想避免分配一个中间变量来传递给
arrfun
。
你是否忽略了这种简单明了的表达方式?
let result = arrfun(someArray.filter(foo).map(bar))
从右向左的功能组合
或许你想要经典(从右到左)的功能组合?
const compose = (f,...fs) => x =>
f === undefined ? x : f(compose(...fs)(x))
const filter = f => xs =>
xs.filter(x => f(x))
const map = f => xs =>
xs.map(x => f(x))
const foo = x =>
x > 3
const bar = x =>
x * x
const arrfun = xs =>
xs.reverse()
const myfunc =
compose(arrfun, map(bar), filter(foo))
let someArray = [1,2,3,4,5,6]
let result = myfunc(someArray)
console.log(result)
// [ 36, 25, 16 ]
从左到右的功能组合
使用从左到右的函数组合
的相同答案
const compose = (f,...fs) => x =>
f === undefined ? x : compose(...fs)(f(x))
const filter = f => xs =>
xs.filter(x => f(x))
const map = f => xs =>
xs.map(x => f(x))
const foo = x =>
x > 3
const bar = x =>
x * x
const arrfun = xs =>
xs.reverse()
// notice order of functions
const myfunc =
compose(filter(foo), map(bar), arrfun)
let someArray = [1,2,3,4,5,6]
let result = myfunc(someArray)
console.log(result)
// [ 36, 25, 16 ]
身份仿函数
我不认为在可读性方面包装整个事物。想象一下,你必须将更多东西链接到arrfun,然后将该东西包装在另一个函数中。
您应该看到this answer我写过关于身份仿函数的文章 - 这为您提供了一个可链接的界面,但不接触原生原型
const Identity = x => ({
runIdentity: x,
map: f => Identity(f(x))
})
const foo = x =>
x > 3
const bar = x =>
x * x
const arrfun = xs =>
xs.reverse()
const myfunc = xs =>
Identity(xs)
.map(xs => xs.filter(foo))
.map(xs => xs.map(bar))
.map(xs => arrfun(xs))
.runIdentity
let someArray = [1,2,3,4,5,6]
let result = myfunc(someArray)
console.log(result)
// [ 35, 25, 16 ]
当然,如果您按照我们之前的定义保留filter
和map
,它会清除myfunc
const Identity = x => ({
runIdentity: x,
map: f => Identity(f(x))
})
const filter = f => xs =>
xs.filter(x => f(x))
const map = f => xs =>
xs.map(x => f(x))
const foo = x =>
x > 3
const bar = x =>
x * x
const arrfun = xs =>
xs.reverse()
const myfunc = x =>
Identity(x)
.map(filter(foo))
.map(map(bar))
.map(arrfun)
.runIdentity
let someArray = [1,2,3,4,5,6]
let result = myfunc(someArray)
console.log(result)
// [ 35, 25, 16 ]
请不要挂在foo
并且预先定义bar
。如果你想
myfunc
内直接使用lambda表达式
const myfunc = xs =>
Identity(xs)
.map(xs => xs.filter(x => x > 3))
.map(xs => xs.map(x => x * x))
.map(arrfun)
// or skip defining arrfun somewhere else and just ...
// .map(xs => xs.reverse())
.runIdentity
答案 1 :(得分:0)
您可以首先将您的操纵器功能和结果函数组合为可重复使用的函数。喜欢:
let arr = [1,2,3,4,5];
const manipulatorFn = arr => arr.map(item => item +1);
const arrFunc = (arr, fn) => fn(arr);
或者如果你想在arrFunc中做更多的东西
const arrFunc = (arr, fn) => {
let a = fn(arr);
// do some more stuff with a
return a;
};
现在您可以获取结果
let result = arrFunc(arr, manipulatorFn);