编写高阶箭头函数

Write Higher Order Arrow Functions

我正在做 FreeCodeCamp 任务,现在我被箭头函数卡住了 问题是:我需要对数组进行排序("filter" 函数运行良好 - 它进行排序)但是我的地图。功能不起作用。我收到错误消息“((num > 0) && Number.isInteger(...)).map 不是函数”

提前致谢

const realNumberArray = [4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2];
const squareList = (arr) => {
  "use strict";
  const squaredIntegers = arr.filter((num) =>
   (num > 0 && Number.isInteger(num)).map((num) => Math.pow(num,2) )) 
  return squaredIntegers;
};

它应该return一个只包含正整数平方的数组。

.map 放在 之后 .filter 完成:

const realNumberArray = [4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2];
const squareList = (arr) => {
  return arr
    .filter(num => num > 0 && Number.isInteger(num))
    .map(num => num ** 2)
};

console.log(squareList(realNumberArray));

你可以在不使用 return 或设置为另一个常量的情况下一起做所有事情:

const realNumberArray = [4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2];

const squareList = (arr) => arr.filter(num => num > 0 && 
   Number.isInteger(num)).map(num => Math.pow(num,2));

您可以只使用 reduce 函数来完成此操作。

const list = [4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2];
const result = list.reduce((acc, val) => {
  if (Number.isInteger(val) && val > 0) {acc.push(val*val)};
  return acc;
}, []);
console.log(result);

但是你说高阶箭头函数^_^

const squareList = arr =>
  $ (arr)                        // beginning with arr,
    (filter (num => num > 0))    // filter
    (filter (Number.isInteger))  // filter some more
    (map (x => x ** 2))          // map
    ($)                          // extract result

const map = f => xs =>
  xs .map (x => f (x))           // Array.prototype.map
  
const filter = f => xs =>
  xs .filter (x => f (x))        // Array.prototype.filter

const $ = x =>      // beginning with x,
  f =>              // and a function, f,
    f === $         // exit condition
      ? x           // return x
      : $ (f (x))   // otherwise, transform x using f and recur

const realNumbers =
  [ 4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2 ]
  
const result =
  squareList (realNumbers)

console.log(result)
// [ 16, 1764, 36 ]

$这样的函数允许我们以不同的方式思考我们的问题。上面我们看到 squareList 获取一个数组并将其垂直向下传递给 "pipe"。直觉上,将问题视为 arr->filter->filter->map 的序列很好,但这是一种浪费的计算。正如其他人指出的那样,它可以用一个 reduce 来完成。如果我们的蛋糕也可以吃,那不是很好吗?

函数式编程就是用函数编程。这并不意味着我们必须放弃以特定方式编写程序。只需编写函数来隔离复杂性并为您完成繁重的工作。

下面,squareList与上面完全一样,但是这次我们通过重构$来显着改变程序的行为。此版本不是按顺序 运行 filter->filter->map,而是建立一个待处理的计算并在弹出值时运行单个 reduce。这种技术的流行名称是 transducers;在这里,我使用箭头函数对它们进行了编码。

几天的高阶箭头函数^_^

const squareList = arr =>
  $ (arr)                       // beginning with arr,
    (filter (num => num > 0))   // add filter transducer
    (filter (Number.isInteger)) // add another filter transducer
    (map (x => x ** 2))         // add map transducer
    ($)                         // run transducer

const map = f =>                   // map transducer
  k => (r, x) => k (r, f (x))
  
const filter = f =>                // filter transducer
  k => (r, x) => f (x) ? k (r, x) : r

const $ = (x, t = identity) =>     // beginning with x and base transducer,
  f =>                             // and a function, f,
    f === $                        // exit condition
      ? x .reduce (t (push), [])   // run transducer; single reduce
      : $ (x, comp (t, f))         // otherwise, recur with new transducer

const identity = x =>
  x

const push = (r, x) =>
  ( r .push (x)
  , r
  )

const comp = (f, g) =>
  x => f (g (x))

const realNumbers =
  [ 4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2 ]
  
const result =
  squareList (realNumbers)

console.log(result)
// [ 16, 1764, 36 ]

以上$只迭代输入数组一次,相比之下filter->filter->map迭代输入数组三次 (3) 次。在 arr 非常大的情况下,这是一个很大的性能提升。

$ 可以是 任何东西 – 因为它是一个函数,它给了我们一个可以控制并做出有意义改变的领域;也许我们会做一些性能优化;如果给出无效参数,它可能会抛出 TypeError ;也许我们称它为 pipetrans 或其他名称。不要认为函数式编程开始和结束于 Array.prototype.mapArray.prototype.filterArray.prototype.reduce 等。 想象魔杖然后创造它^_^