将功能链的结果传递给功能

时间:2017-05-23 08:19:52

标签: javascript functional-programming

如果我有一个数组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是这个功能的最佳名称吗? pipechain

新示例

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) || []) ,您将如何解决这个问题?

2 个答案:

答案 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 ]

当然,如果您按照我们之前的定义保留filtermap,它会清除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);