ES6 Generator 函数 实现斐波那契数列

61 阅读1分钟

今天翻到了阮一峰大神的文档 ,突然之间想起来了之前的一个面试题:ES6 如何实现一个斐波那契数列 。可怜的我当时都不知道 斐波那契数列 是什么,更不知道 ES6 怎么实现,回来后看了看虽然会了,没整理下来,今天看到,就记录一下~

/**
 * 返回长度为 len 的 斐波那契数列
 * 0,1,1,2,3,5,...
 * @param {*} m 
 */
function* fibonacci(){
  let [prev, current] = [0, 1];
  for(;;) {
    // yield prev; // 返回数据从 0 开始
    yield current; // 返回数据从 1 开始
    [prev, current] = [current, prev + current];
  }
}

function getFibonacci(len) {
  let aFibonacci = [];
  for(let n of fibonacci()) {
    if(aFibonacci.length >= len) {
      break;
    } 
    aFibonacci.push(n);
  }
  return aFibonacci;
}
const fibonacci2 = getFibonacci(2);
const fibonacci5 = getFibonacci(5);
const fibonacci10 = getFibonacci(10);
console.log('fibonacci2:', fibonacci2); // [ 1, 1 ]
console.log('fibonacci5:', fibonacci5); // [ 1, 1, 2, 3, 5 ]
console.log('fibonacci10:', fibonacci10); // [ 1,  1,  2,  3,  5, 8, 13, 21, 34, 55 ]

这里将斐波那契数列的数据逻辑与长度要求拆成了两个原子,并用了 Generator 函数的两个概念:for...of 和 yield 。当然也可以不拆开,直接实现,如下:

function* getFibonacci2(len){
  let [prev, current] = [0, 1];
  for(let i = 0; i < len; i++) {
    // yield prev; // 返回数据从 0 开始
    yield current; // 返回数据从 1 开始
    [prev, current] = [current, prev + current];
  }
}
const fibonacci2 = [...getFibonacci2(2)];
const fibonacci5 = [...getFibonacci(5)];
const fibonacci10 = [...getFibonacci(10)];
console.log('fibonacci2:', fibonacci2); // [ 1, 1 ]
console.log('fibonacci5:', fibonacci5); // [ 1, 1, 2, 3, 5 ]
console.log('fibonacci10:', fibonacci10); // [ 1,  1,  2,  3,  5, 8, 13, 21, 34, 55 ]