RxJS 笔记 03

参考 简书原文 作者:readilen

RxJS 核心的 Observable 操作观念跟 FP 的阵列操作是极为相近的,
只学会以下几个基本的方法跟观念后,会让我们之后上手 Observable 简单很多!

1. forEach

forEach 是 JavaScript 在 ES5 后,原生就有支援的方法。

var arr = ['Jerry', 'Anna'];

for(var i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

arr.forEach(item => console.log(item));

2. 练习手写 Map 函数 (prototype chain 原型链)

ES5 之后原生的 JavaScript 阵列有 map 方法

思路

  1. 我们会让每个 阵列 都有一个 map 方法
  2. 这个方法会让使用者自订传入一个 callback function
  3. 这个 callback function 会回传使用者预期的元素
// 我们希望每一个阵列都有 map 这个方法,
// 所以我们在 Array.prototype 扩充 map function
Array.prototype.map = (callback) => {
    if (typeof callback !== 'function') {
        return this;
    }

    // map 最后一定会返回一个新阵列,
    // 所以我们先宣告一个新阵列
    let result = [];

    // this 就是呼叫 map 的阵列
    this.forEach((el, index) => {
        // 执行使用者定义的 callback,
        // callback 会回传使用者预期的元素,
        // 所以我们把它 push 进新阵列
        result.push(callback(el, index));
    });

    return result;
}

3. 练习手写 Filter 函数

思路

  1. 遍历 newCourseList 中的所有元素
  2. 判断元素是否符合条件,符合则加到新的阵列中
Array.prototype.filter = (callback) => {
    if (typeof callback !== 'function') {
        return this;
    }

    let result = [];

    this.forEach((el, index) => {
        if (callback(el, index)) {
            result.push(el);
        }
    });

    return result;
}

4. 摊平二维阵列

Array.prototype.concatAll = function() {
  var result = [];

  // 用 apply 完成
  this.forEach((array) => {
    result.push.apply(result, array);
  });

  // 用两个 forEach 完成
  // this.forEach((array) => {
  //   array.forEach(item => {
  //     result.push(item)
  //   })
  // });

  // 用 ES6 spread 完成 / 解构
  // this.forEach((array) => {
  //   result.push(...array);
  // })

  return result;
};

综合练习

var courseLists = [{
      "name": "My Courses",
      "courses": [{
        "id": 511019,
        "title": "React for Beginners",
        "covers": [{
          width: 150,
          height: 200,
          url: "http://placeimg.com/150/200/tech"
        }, {
          width: 200,
          height: 200,
          url: "http://placeimg.com/200/200/tech"
        }, {
          width: 300,
          height: 200,
          url: "http://placeimg.com/300/200/tech"
        }],
        "tags": [{
          id: 1,
          name: "JavaScript"
        }],
        "rating": 5
      }, {
        "id": 511020,
        "title": "Front-End automat workflow",
        "covers": [{
          width: 150,
          height: 200,
          url: "http://placeimg.com/150/200/arch"
        }, {
          width: 200,
          height: 200,
          url: "http://placeimg.com/200/200/arch"
        }, {
          width: 300,
          height: 200,
          url: "http://placeimg.com/300/200/arch"
        }],
        "tags": [{
          "id": 2,
          "name": "gulp"
        }, {
          "id": 3,
          "name": "webpack"
        }],
        "rating": 5
      }]
    }, {
      "name": "New Release",
      "courses": [{
        "id": 511022,
        "title": "Vue2 for Beginners",
        "covers": [{
          width: 150,
          height: 200,
          url: "http://placeimg.com/150/200/nature"
        }, {
          width: 200,
          height: 200,
          url: "http://placeimg.com/200/200/nature"
        }, {
          width: 300,
          height: 200,
          url: "http://placeimg.com/300/200/nature"
        }],
        "tags": [{
          id: 1,
          name: "JavaScript"
        }],
        "rating": 5
      }, {
        "id": 511023,
        "title": "Angular2 for Beginners",
        "covers": [{
          width: 150,
          height: 200,
          url: "http://placeimg.com/150/200/people"
        }, {
          width: 200,
          height: 200,
          url: "http://placeimg.com/200/200/people"
        }, {
          width: 300,
          height: 200,
          url: "http://placeimg.com/300/200/people"
        }],
        "tags": [{
          id: 1,
          name: "JavaScript"
        }],
        "rating": 5
      }]
    }];

    Array.prototype.concatAll = function (callback) {
      var result = [];
      if (typeof callback === 'function') {
        this.forEach(function (array) {
          result.push(callback(array));
        });
      } else {
        this.forEach(function (array) {
           result.push.apply(result, array);
        });
        // this.forEach(function (array) {
        //    array.forEach(function (item) {
        //      result.push(item);
        //    });
        // });
      }
      return result;
    }

    // obj.courses[0].covers[0].url id title
    console.log(courseLists.map(function(el) {
        return el.courses
    }).concatAll().concatAll(function (el) {
      var result = []

      el.covers.forEach((o) => {
        result.push({
          id: el.id,
          title: el.title,
          cover: o.url
        })
      })

      return result.filter(function (j) {
        return j.cover.indexOf('150') > -1;
      });
    }).concatAll())

    console.log(courseLists.map(list =>
     list.courses.map(course => {
      return course.covers.filter(cover => cover.width === 150)
        .map(item => ({
          id: course.id,
          title: course.title,
          cover: item.url
        }))
    })).concatAll().concatAll())