每周分享:函数式编程之递归模式

函数式编程(FP)就是利用纯函数来构建软件的过程,避免共享状态,可变数组以及一些副作用。而 ES6 带来了很多的特性帮助我们更方便地进行 JavaScript 函数式编程。

今天我们就来看看 ES6 的剩余参数语法结合递归实现如何实现函数式编程,用函数式思想实现一些我们常用的方法。

返回数组的第一个元素

const head = ([x]) => x

使用

const arr = [1, 2, 3]
head(arr) // 1

Tail

返回数组中除第一个元素外的其它元素

const tail = ([, ...xs]) => xs

上面写法中省略了第一个参数,所以也等价于

const tail = ([x, ...xs]) => xs

使用

const arr = [1, 2, 3]
tail(arr) // [2, 3]

Def

如果存在参数则返回 true,否则返回 false

const def = x => typeof x !== "undefined"

使用

const name = "tom"
def(name) // true
def(age) // false

Copy

复制数组

const copy = arr => [...arr]

使用

let arr = [1, 2, 3]
let copied = copy(arr)
copied.push(4)
arr // [1, 2, 3]
copied // [1, 2, 3, 4]

Reverse

反转数组

const reverse = ([x, ...xs]) => def(x) ? [...reverse(xs), x] : []

这里我们通过递归依次将整个数组给调换顺序了,使用

const arr = [1, 2, 3]
reverse(arr) // [3, 2, 1]

First

返回一个新的数组,包含给定数组前 n 项的元素

const first = ([x, ...xs], n = 1) => def(x) && n ? [x, ...first(xs, n - 1)] : []

同样运用了递归的思想,使用

const arr = [1, 2, 3]
first(arr, 2) // [1, 2]

计算过程如下

  • 首先 first(arr, 2) = first([1, 2, 3], 2)
  • def(x) = def(1) && n = 2 => true
  • 返回 [x, ...first(xs, n - 1)] = [1, ...first([2, 3], 1)]
  • 计算 first([2, 3], 1)
  • def(x) = def(2) && n = 1 => true
  • 返回 [x, ...first(xs, n - 1)] = [2, ...first([3], 0)]
  • 计算 first([3], 0)
  • def(x) = def(3) && n = 0 => false
  • 于是 first([3], 0) 返回 []
  • 所以结果为 [1, ...[2, ...[]]] => [1, 2]

Last

返回一个新的数组,包含给定数组后 n 项的元素

const last = (xs, n = 1) => reverse(first(reverse(xs), n))

结合上面的 first 方法和反转,使用

const arr = [1, 2, 3]
last(arr, 2) // [2, 3]

本期的主要目的不是为了让大家在实际开发中就这样去上面的方法,实际上数组也提供了相应的便捷方法,之所以讲这些,是为了让大家更加深刻理解函数式编程的纯函数特性。

最新评论

  1. First off I want to say fantastic blog! I had a quick question in which
    I’d like to ask if you don’t mind. I was interested to know how you center yourself and clear
    your head prior to writing. I have had difficulty clearing
    my mind in getting my ideas out there. I truly do
    take pleasure in writing but it just seems like the first 10 to 15 minutes tend to be wasted just trying to figure out how to begin. Any suggestions or tips?
    Kudos!

  2. I loved your humor spread throughout your post. It is funny how we are afraid to pray for patience because God might give us some soon. We do also tend to get a little arrogant with our time because we think what we are doing is so much more important than others. We need to practice and watch Jesus so we can get the patience we need. Thanks Chip. Forrest Kunc

  3. Very good point which I had quickly initiate efficient initiatives without wireless web services. Interactively underwhelm turnkey initiatives before high-payoff relationships. Holisticly restore superior interfaces before flexible technology. Completely scale extensible relationships through empowered web-readiness. Virgil Sadik

  4. I would like to get across my admiration for your generosity in support of men and women who require help with this one concept. Your special dedication to getting the message along ended up being extremely valuable and has truly helped guys and women just like me to achieve their endeavors. The warm and friendly hints and tips can mean a lot a person like me and substantially more to my fellow workers. Thanks a ton; from each one of us. Marco Gajica

  5. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Ambrose Ganino

发表评论

邮箱地址不会被公开。 必填项已用*标注