RxJS 笔记 03
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 方法
思路
- 我们会让每个 阵列 都有一个 map 方法
- 这个方法会让使用者自订传入一个 callback function
- 这个 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 函数
思路
- 遍历 newCourseList 中的所有元素
- 判断元素是否符合条件,符合则加到新的阵列中
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())