JS函数式编程——来源freecodecamp

使用 map 方法从数组中提取数据

让我们从一些简单的数组函数开始,这些函数是数组对象原型上的方法。在本练习中,我们来了解下数组的map方法(即Array.prototype.map())。

请记住,map方法是迭代数组中每一项的方式之一。在对每个元素应用回调函数后,它会创建一个新数组(不改变原来的数组)。
watchList数组保存了包含一些电影信息的对象。使用map从watchList中提取标题(title)和评分(rating),并将新数组保存在rating变量里。目前编辑器中的代码是使用for循环实现,使用map表达式替换循环功能。

// 全局变量
var watchList = [
                 {  
                   "Title": "Inception",
                   "Year": "2010",
                   "Rated": "PG-13",
                   "Released": "16 Jul 2010",
                   "Runtime": "148 min",
                   "Genre": "Action, Adventure, Crime",
                   "Director": "Christopher Nolan",
                   "Writer": "Christopher Nolan",
                   "Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Ellen Page, Tom Hardy",
                   "Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
                   "Language": "English, Japanese, French",
                   "Country": "USA, UK",
                   "Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
                   "Metascore": "74",
                   "imdbRating": "8.8",
                   "imdbVotes": "1,446,708",
                   "imdbID": "tt1375666",
                   "Type": "movie",
                   "Response": "True"
                },
                {  
                   "Title": "Interstellar",
                   "Year": "2014",
                   "Rated": "PG-13",
                   "Released": "07 Nov 2014",
                   "Runtime": "169 min",
                   "Genre": "Adventure, Drama, Sci-Fi",
                   "Director": "Christopher Nolan",
                   "Writer": "Jonathan Nolan, Christopher Nolan",
                   "Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
                   "Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
                   "Language": "English",
                   "Country": "USA, UK",
                   "Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
                   "Metascore": "74",
                   "imdbRating": "8.6",
                   "imdbVotes": "910,366",
                   "imdbID": "tt0816692",
                   "Type": "movie",
                   "Response": "True"
                },
                {
                   "Title": "The Dark Knight",
                   "Year": "2008",
                   "Rated": "PG-13",
                   "Released": "18 Jul 2008",
                   "Runtime": "152 min",
                   "Genre": "Action, Adventure, Crime",
                   "Director": "Christopher Nolan",
                   "Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
                   "Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
                   "Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
                   "Language": "English, Mandarin",
                   "Country": "USA, UK",
                   "Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
                   "Metascore": "82",
                   "imdbRating": "9.0",
                   "imdbVotes": "1,652,832",
                   "imdbID": "tt0468569",
                   "Type": "movie",
                   "Response": "True"
                },
                {  
                   "Title": "Batman Begins",
                   "Year": "2005",
                   "Rated": "PG-13",
                   "Released": "15 Jun 2005",
                   "Runtime": "140 min",
                   "Genre": "Action, Adventure",
                   "Director": "Christopher Nolan",
                   "Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
                   "Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
                   "Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
                   "Language": "English, Urdu, Mandarin",
                   "Country": "USA, UK",
                   "Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
                   "Metascore": "70",
                   "imdbRating": "8.3",
                   "imdbVotes": "972,584",
                   "imdbID": "tt0372784",
                   "Type": "movie",
                   "Response": "True"
                },
                {
                   "Title": "Avatar",
                   "Year": "2009",
                   "Rated": "PG-13",
                   "Released": "18 Dec 2009",
                   "Runtime": "162 min",
                   "Genre": "Action, Adventure, Fantasy",
                   "Director": "James Cameron",
                   "Writer": "James Cameron",
                   "Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
                   "Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
                   "Language": "English, Spanish",
                   "Country": "USA, UK",
                   "Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
                   "Metascore": "83",
                   "imdbRating": "7.9",
                   "imdbVotes": "876,575",
                   "imdbID": "tt0499549",
                   "Type": "movie",
                   "Response": "True"
                }
];

// 请在本行以下添加你的代码

var rating = [];
rating = watchList.map((item)=>({"title":item["Title"],"rating":item["imdbRating"]}));

// 请在本行以上添加你的代码

console.log(rating); 

在原型上实现 map 方法(原生实现map方法)

我们之前用map方法(即Array.prototype.map())返回一个与调用它的数组长度相同的数组。只要它的回调函数不改变原始数组,它就不会改变原始数组。

换句话说,map是一个纯函数,它的输出仅取决于输入的数组和作为参数传入的回调函数。

为了加深对map方法的理解,现在我们来用for或Array.prototype.forEach()自己实现一下这个方法。

注意:纯函数可以改变其作用域内定义的局部变量,但我们最好不要这样做。

// 全局变量
var s = [23, 65, 98, 5];

Array.prototype.myMap = function(callback){
  var newArray = [];
  // 请在本行以下添加你的代码
  this.forEach(a => newArray.push(callback(a)));
  // 请在本行以上添加你的代码
  return newArray;

};

var new_s = s.myMap(function(item){
  return item * 2;
});

使用 filter 方法从数组中提取数据

另一个有用的数组方法是filter()(即Array.prototype.filter())。filter方法会返回一个长度不大于原始数组的新数组。

和map一样,Filter不会改变原始数组,它接收一个回调函数,将回调内的逻辑应用于数组的每个元素。新数组包含根据回调函数内条件返回 true 的元素。

// 全局变量
var watchList = [
                 {  
                   "Title": "Inception",
                   "Year": "2010",
                   "Rated": "PG-13",
                   "Released": "16 Jul 2010",
                   "Runtime": "148 min",
                   "Genre": "Action, Adventure, Crime",
                   "Director": "Christopher Nolan",
                   "Writer": "Christopher Nolan",
                   "Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Ellen Page, Tom Hardy",
                   "Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
                   "Language": "English, Japanese, French",
                   "Country": "USA, UK",
                   "Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
                   "Metascore": "74",
                   "imdbRating": "8.8",
                   "imdbVotes": "1,446,708",
                   "imdbID": "tt1375666",
                   "Type": "movie",
                   "Response": "True"
                },
                {  
                   "Title": "Interstellar",
                   "Year": "2014",
                   "Rated": "PG-13",
                   "Released": "07 Nov 2014",
                   "Runtime": "169 min",
                   "Genre": "Adventure, Drama, Sci-Fi",
                   "Director": "Christopher Nolan",
                   "Writer": "Jonathan Nolan, Christopher Nolan",
                   "Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
                   "Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
                   "Language": "English",
                   "Country": "USA, UK",
                   "Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
                   "Metascore": "74",
                   "imdbRating": "8.6",
                   "imdbVotes": "910,366",
                   "imdbID": "tt0816692",
                   "Type": "movie",
                   "Response": "True"
                },
                {
                   "Title": "The Dark Knight",
                   "Year": "2008",
                   "Rated": "PG-13",
                   "Released": "18 Jul 2008",
                   "Runtime": "152 min",
                   "Genre": "Action, Adventure, Crime",
                   "Director": "Christopher Nolan",
                   "Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
                   "Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
                   "Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
                   "Language": "English, Mandarin",
                   "Country": "USA, UK",
                   "Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
                   "Metascore": "82",
                   "imdbRating": "9.0",
                   "imdbVotes": "1,652,832",
                   "imdbID": "tt0468569",
                   "Type": "movie",
                   "Response": "True"
                },
                {  
                   "Title": "Batman Begins",
                   "Year": "2005",
                   "Rated": "PG-13",
                   "Released": "15 Jun 2005",
                   "Runtime": "140 min",
                   "Genre": "Action, Adventure",
                   "Director": "Christopher Nolan",
                   "Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
                   "Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
                   "Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
                   "Language": "English, Urdu, Mandarin",
                   "Country": "USA, UK",
                   "Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
                   "Metascore": "70",
                   "imdbRating": "8.3",
                   "imdbVotes": "972,584",
                   "imdbID": "tt0372784",
                   "Type": "movie",
                   "Response": "True"
                },
                {
                   "Title": "Avatar",
                   "Year": "2009",
                   "Rated": "PG-13",
                   "Released": "18 Dec 2009",
                   "Runtime": "162 min",
                   "Genre": "Action, Adventure, Fantasy",
                   "Director": "James Cameron",
                   "Writer": "James Cameron",
                   "Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
                   "Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
                   "Language": "English, Spanish",
                   "Country": "USA, UK",
                   "Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
                   "Metascore": "83",
                   "imdbRating": "7.9",
                   "imdbVotes": "876,575",
                   "imdbID": "tt0499549",
                   "Type": "movie",
                   "Response": "True"
                }
];

// 请在本行以下添加你的代码

var filteredList = watchList.map(function(e) {
  return {title: e["Title"], rating: e["imdbRating"]}
}).filter((e) => e.rating >= 8);

// 请在本行以上添加你的代码

console.log(filteredList); 

在原型上实现 filter 方法(原生实现filter方法)

为了加深对filter的理解,现在我们来自己实现一下Array.prototype.filter()方法。

可以用for循环或Array.prototype.forEach()。

请注意:纯函数可以改变其作用域内定义的局部变量,但我们最好不要这样做。

// the global Array
var s = [23, 65, 98, 5];

Array.prototype.myFilter = function(callback){
  var newArray = [];
  // Add your code below this line
  this.forEach(function(x) {
    if (callback(x) == true) {
      newArray.push(x);
    }
  })
  // Add your code above this line
  return newArray;

};
Array.prototype.myFilter = function(callback){
  var newArray = [];
  // Add your code below this line
  for (let i=0; i<this.length;i++){
    if(callback(this[i])=== true ){
 newArray.push(this[i]);
    }
  }
  // Add your code above this line
  return newArray;

};

var new_s = s.myFilter(function(item){
  return item % 2 === 1;
});

使用 slice 方法返回数组的一部分

slice方法可以从已有数组中返回指定元素。它接受两个参数,第一个规定从何处开始选取,第二个规定从何处结束选取(不包括该元素)。如果没有传参,则默认为从数组的开头开始到结尾结束,这是复制整个数组的简单方式。slice返回一个新数组,不会修改原始数组。

var arr = ["Cat", "Dog", "Tiger", "Zebra"];
var newArray = arr.slice(1, 3);
// 将新数组设置为 ["Dog", "Tiger"]

使用 slice 而不是 splice 从数组中移除元素

使用数组时经常遇到要删除一些元素并保留数组剩余部分的情况。为此,JavaScript 提供了splice方法,它接收两个参数:从哪里开始删除项目的索引,和要删除的项目数。如果没有提供第二个参数,默认情况下是移除到结尾的元素。但splice方法会改变调用它的原始数组。举个例子:

var cities = ["Chicago", "Delhi", "Islamabad", "London", "Berlin"];
cities.splice(3, 1); // 返回 "London" 并将它从 cities 数组删除
// cities 现在是 ["Chicago", "Delhi", "Islamabad", "Berlin"]

正如我们在上一次挑战中看到的那样,slice方法不会改变原始数组,而是返回一个可以保存到变量中的新数组。回想一下,slice方法接收两个参数,从开始索引开始选取到结束(不包括该元素),并在新数组中返回这些元素。使用slice方法替代splice有助于避免数组变化产生的副作用。
用slice代替splice重写nonMutatingSplice函数。将cities数组长度限制为3,并返回一个仅包含前 3 项的新数组。

不要改变提供给函数的原始数组。

function nonMutatingSplice(cities) {
  // 请在本行以下添加你的代码
  return cities.slice(0,3);
  
  // 请在本行以上添加你的代码
}
var inputCities = ["Chicago", "Delhi", "Islamabad", "London", "Berlin"];
nonMutatingSplice(inputCities);

使用 concat 方法组合两个数组

Concatenation意思是将元素连接到尾部。同理,JavaScript 为字符串和数组提供了concat方法。对数组来说,在一个数组上调用concat方法,然后提供另一个数组作为参数添加到第一个数组末尾,返回一个新数组,不会改变任何一个原始数组。举个例子:

[1, 2, 3].concat([4, 5, 6]);
// 返回新数组 [1, 2, 3, 4, 5, 6]

使用 concat 而不是 push 将元素添加到数组的末尾

函数式编程就是创建和使用 non-mutating 函数。

最后一个挑战介绍了concat方法,这是一种在不改变原始数组的前提下,将数组组合成新数组的方法。将concat方法与push方法做比较,Push将元素添加到调用它的数组的末尾,这样会改变该数组。举个例子:

var arr = [1, 2, 3];
arr.push([4, 5, 6]);
// arr 变成了 [1, 2, 3, [4, 5, 6]]
// 不是函数式编程

Concat方法可以将新项目添加到数组末尾,而不产生任何变更副作用。

使用 reduce 方法分析数据

reduce()(即Array.prototype.reduce()),是 JavaScript 所有数组操作中最通用的方法。几乎可以用reduce方法解决所有数组处理问题。

filter和map方法不支持对数组中两个不同元素的交互。举个例子,如果你想把数组中的元素拿来比较或者相加,用filter和map是做不到的。

reduce方法允许更通用的数组处理方式,而且filter和map方法都可以当作是reduce的特殊实现。

然而,在我们介绍它们的特殊实现之前,我们先来练习使用reduce。
watchList变量中包含一组存有多部电影信息对象。使用reduce查找由 Christopher Nolan 导演的电影directed by Christopher Nolan的 IMDB 评级。回想一下之前的挑战,如何filter数据,以及使用map来获取你想要的数据。你可能需要创建一些变量,但是请将最后的平均值保存到averageRating变量中。请注意,评级在对象中是字符串,需要将其转换为数字再用于数学运算。

// 全局变量
var watchList = [
                 {  
                   "Title": "Inception",
                   "Year": "2010",
                   "Rated": "PG-13",
                   "Released": "16 Jul 2010",
                   "Runtime": "148 min",
                   "Genre": "Action, Adventure, Crime",
                   "Director": "Christopher Nolan",
                   "Writer": "Christopher Nolan",
                   "Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Ellen Page, Tom Hardy",
                   "Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
                   "Language": "English, Japanese, French",
                   "Country": "USA, UK",
                   "Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
                   "Metascore": "74",
                   "imdbRating": "8.8",
                   "imdbVotes": "1,446,708",
                   "imdbID": "tt1375666",
                   "Type": "movie",
                   "Response": "True"
                },
                {  
                   "Title": "Interstellar",
                   "Year": "2014",
                   "Rated": "PG-13",
                   "Released": "07 Nov 2014",
                   "Runtime": "169 min",
                   "Genre": "Adventure, Drama, Sci-Fi",
                   "Director": "Christopher Nolan",
                   "Writer": "Jonathan Nolan, Christopher Nolan",
                   "Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
                   "Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
                   "Language": "English",
                   "Country": "USA, UK",
                   "Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
                   "Metascore": "74",
                   "imdbRating": "8.6",
                   "imdbVotes": "910,366",
                   "imdbID": "tt0816692",
                   "Type": "movie",
                   "Response": "True"
                },
                {
                   "Title": "The Dark Knight",
                   "Year": "2008",
                   "Rated": "PG-13",
                   "Released": "18 Jul 2008",
                   "Runtime": "152 min",
                   "Genre": "Action, Adventure, Crime",
                   "Director": "Christopher Nolan",
                   "Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
                   "Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
                   "Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
                   "Language": "English, Mandarin",
                   "Country": "USA, UK",
                   "Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
                   "Metascore": "82",
                   "imdbRating": "9.0",
                   "imdbVotes": "1,652,832",
                   "imdbID": "tt0468569",
                   "Type": "movie",
                   "Response": "True"
                },
                {  
                   "Title": "Batman Begins",
                   "Year": "2005",
                   "Rated": "PG-13",
                   "Released": "15 Jun 2005",
                   "Runtime": "140 min",
                   "Genre": "Action, Adventure",
                   "Director": "Christopher Nolan",
                   "Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
                   "Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
                   "Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
                   "Language": "English, Urdu, Mandarin",
                   "Country": "USA, UK",
                   "Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
                   "Metascore": "70",
                   "imdbRating": "8.3",
                   "imdbVotes": "972,584",
                   "imdbID": "tt0372784",
                   "Type": "movie",
                   "Response": "True"
                },
                {
                   "Title": "Avatar",
                   "Year": "2009",
                   "Rated": "PG-13",
                   "Released": "18 Dec 2009",
                   "Runtime": "162 min",
                   "Genre": "Action, Adventure, Fantasy",
                   "Director": "James Cameron",
                   "Writer": "James Cameron",
                   "Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
                   "Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
                   "Language": "English, Spanish",
                   "Country": "USA, UK",
                   "Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
                   "Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
                   "Metascore": "83",
                   "imdbRating": "7.9",
                   "imdbVotes": "876,575",
                   "imdbID": "tt0499549",
                   "Type": "movie",
                   "Response": "True"
                }
];

// 请在本行以下添加你的代码

var averageRating = watchList.filter(x => x.Director === "Christopher Nolan").map(x => Number(x.imdbRating)).reduce((x1, x2) => x1 + x2) / watchList.filter(x => x.Director === "Christopher Nolan").length;

// 请在本行以上添加你的代码

console.log(averageRating); 

使用 sort 方法按字母顺序给数组排序

sort方法可以根据回调函数对数组元素进行排序。
举个例子:

function ascendingOrder(arr) {
  return arr.sort(function(a, b) {
    return a - b;
  });
}
ascendingOrder([1, 5, 2, 3, 4]);
// Returns [1, 2, 3, 4, 5]

function reverseAlpha(arr) {
  return arr.sort(function(a, b) {
    return a < b;
  });
}
reverseAlpha(['l', 'h', 'z', 'b', 's']);
// 返回 ['z', 's', 'l', 'h', 'b']

在不更改原始数组的前提下返回排序后的数组

sort方法会产生改变原始数组中元素顺序的副作用。换句话说,它会改变数组的位置。避免这种情况的一种方法是先将空数组连接到正在排序的数组上(记住concat返回一个新数组),再用sort方法。

var globalArray = [5, 6, 3, 2, 9];
function nonMutatingSort(arr) {
  // Add your code below this line
  return [].concat(arr).sort(function(a, b) {
    return a - b;
  });
  // Add your code above this line
}
nonMutatingSort(globalArray);

使用 split 方法将字符串拆分成数组

split方法用于把字符串分割成字符串数组,接收一个分隔符参数,分隔符可以是用于分解字符串或正则表达式的字符。举个例子,如果分隔符是空格,你会得到一个单词数组;如果分隔符是空字符串,你会得到一个由字符串中每个字符组成的数组。

下面是两个用空格分隔一个字符串的例子,另一个是用数字的正则表达式分隔:

var str = "Hello World";
var bySpace = str.split(" ");
// Sets bySpace to ["Hello", "World"]

var otherString = "How9are7you2today";
var byDigits = str.split(/\d/);
// Sets byDigits to ["How", "are", "you", "today"]

因为字符串是固定的,split方法可以更简单的操作它们。
在splitify函数中用split方法将str分割成单词数组,这个方法应该返回一个数组。单词不一定都是用空格分隔,所以数组中不应包含标点符号。

function splitify(str) {
  // 请在本行以下添加你的代码
  return str.split(/\W/);
  
  // 请在本行以上添加你的代码
}
splitify("Hello World,I-am code");

使用 join 方法将数组组合成字符串

join方法用来把数组中的所有元素放入一个字符串,并通过指定的分隔符参数进行分隔。

var arr = ["Hello", "World"];
var str = arr.join(" ");
// Sets str to "Hello World"

在函数sentensify内用join方法(及其他方法)用字符串str中的单词造句,这个函数应返回一个字符串。举个例子,“I-like-Star-Wars” 会被转换成 “I like Star Wars”。在此挑战中请勿使用replace方法。

function sentensify(str) {
  // 请在本行以下添加你的代码
  return str.split(/\W/).join(' ');
  
  // 请在本行以上添加你的代码
}
sentensify("May-the-force-be-with-you");

应用函数式编程将字符串转换为URL片段

最后几个挑战中涵盖了许多符合函数式编程原则并在处理数组和字符串中非常有用的方法。我们还学习了强大的、可以将问题简化为更简单形式的reduce方法,从计算平均值到排序,任何数组操作都可以用它来实现。回想一下,map和filter方法都是reduce的特殊实现。

让我们把学到的知识结合起来解决一个实际问题。

许多内容管理站点(CMS)为了让添加书签更简单,会将帖子的标题添加到 URL 上。举个例子,如果你写了一篇标题为 “Stop Using Reduce” 的帖子,URL很可能会包含标题字符串的某种形式 (如:"…/stop-using-reduce"),你可能已经在 freeCodeCamp 网站上注意到了这一点。
填写urlSlug函数,使其转换字符串title带有连字符号的 URL 版本。您可以使用本节中介绍的任何方法,但不要用replace方法。以下是本次挑战的要求:

输入包含空格和标题大小写单词的字符串

输出字符串,单词之间的空格用连字符(-)替换

输出应该是小写字母

输出不应有任何空格

// the global variable
var globalTitle = "Winter Is Coming";

// Add your code below this line
function urlSlug(title) {
  return title.toLowerCase().trim().split(/\s+/).join('-');
}
// Add your code above this line

var winterComing = urlSlug(globalTitle); // Should be "winter-is-coming"

使用 every 方法检查数组中的每个元素是否符合条件

every方法用于检测数组中所有元素是否都符合指定条件。如果所有元素满足条件,返回布尔值true,反之返回false。

举个例子,下面的代码检测数组numbers的所有元素是否都小于 10:

var numbers = [1, 5, 8, 0, 10, 11];
numbers.every(function(currentValue) {
  return currentValue < 10;
});
// 返回 false

在checkPositive函数中使用every方法检查arr中是否所有元素都是正数,函数应返回一个布尔值。

function checkPositive(arr) {
  // 请在本行以下添加你的代码
  arr.every(function(a){
      return a > 0;
  })
  
  // 请在本行以上添加你的代码
}
checkPositive([1, 2, 3, -4, 5]);

在checkPositive函数值中使用some检查arr中是否有元素为正数,函数应返回一个布尔值。

function checkPositive(arr) {
  // 请在本行以下添加你的代码
  return arr.every(val => val > 0);
  
  // 请在本行以上添加你的代码
}
checkPositive([1, 2, 3, -4, 5]);

使用 some 方法检查数组中是否有元素是否符合条件

some方法用于检测数组中任何元素是否满足指定条件。如果有一个元素满足条件,返回布尔值true,反之返回false。

举个例子,下面的代码检测数组numbers中是否有元素小于10:

var numbers = [10, 50, 8, 220, 110, 11];
numbers.some(function(currentValue) {
  return currentValue < 10;
});
// 返回 true

函数柯里化

arity是函数所需的形参的数量。函数Currying意思是把接受多个arity的函数变换成接受单一arity的函数。

换句话说,就是重构函数让它接收一个参数,然后返回接收下一个参数的函数,依此类推。

举个例子:

//Un-curried function
function unCurried(x, y) {
  return x + y;
}

// 柯里化函数
function curried(x) {
  return function(y) {
    return x + y;
  }
}
curried(1)(2) // 返回 3

柯里化在不能一次为函数提供所有参数情况下很有用。因为它可以将每个函数的调用保存到一个变量中,该变量将保存返回的函数引用,该引用在下一个参数可用时接受该参数。下面是使用curried函数的例子:

// Call a curried function in parts:
var funcForY = curried(1);
console.log(funcForY(2)); // 打印 3

类似地,partial application的意思是一次对一个函数应用几个参数,然后返回另一个应用更多参数的函数。

//Impartial function
function impartial(x, y, z) {
  return x + y + z;
}
var partialFn = impartial.bind(this, 1, 2);
partialFn(10); // 返回 13

填写add函数主体部分,用柯里化添加参数x,y和z.

function add(x) {
  // 请在本行以下添加你的代码
  return function(y){
    return function(z){
      return x+y+z;
    }
  }
  
  // 请在本行以上添加你的代码
}
add(10)(20)(30);
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值