js基本函数式编程数组的一些常用方法
编辑时间:2021-09-27 作者:金满斗 浏览量:1804 来源:原创

继续接上篇文章网站

数组的map方法,回调函数接收三个参数。 第一个参数是当前正在被处理的元素。 第二个参数是这个元素的索引,第三个参数是在其上调用该方法的数组

简单例子

看下在 users 上使用 map 方法的例子,返回了一个新数组只包含了用户的名字。 为了简化,例子里只使用了回调函数的第一个参数。
const users = [
  { name: 'John', age: 34 },
  { name: 'Amy', age: 20 },
  { name: 'camperCat', age: 10 }
];

const names = users.map(user => user.name);
console.log(names);
控制台将显示值 [ 'John', 'Amy', 'camperCat' ]。

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

例子:
watchList 数组保存了包含一些电影信息的对象。 在 watchList 上使用 map,将一个新的对象数组赋值给 ratings 变量。 新数组中的每个电影都只能有一个值为电影名称的 title 键,和一个值为 IMDB 评级的 rating 键,不用for循环

// 全局变量
var watchList = [
  {
    "Title": "Batman Begins",
    "Type": "movie",
    "Response": "True",
    'imdbRating':'kdkllk'
  },
  {
    "Title": "Avatar",
    "Type": "movie",
    "Response": "True",
    'imdbRating':'kdkllk'
  }
];
var ratings = watchList.map(
  item=>({
    title: item['Title'],
    rating: item["imdbRating"]
  }
  ));
console.log(JSON.stringify(ratings));

在原型上实现 map 方法

// 全局变量
var s = [23, 65, 98, 5];
Array.prototype.myMap = function(callback) {
  var newArray = [];
  let Narray =  this.slice();
  for(let i=0;i<Narray.length;i++){
      newArray.push(callback(Narray[i]));
  }
  return newArray;
};
var new_s = s.myMap(function(item) {
  return item * 2;
});


 filter 和map基本差不多。只不过是过滤

filter 接收一个回调函数,将回调函数内的逻辑应用于数组的每个元素,新数组包含根据回调函数内条件返回 true 的元素。 换言之,它根据传递给它的函数过滤数组。 和 map 一样,filter 不会改变原始数组。
回调函数接收三个参数。 第一个参数是当前正在被处理的元素。 第二个参数是这个元素的索引,第三个参数是在其上调用 filter 方法的数组。

简单例子

看下在 users 上使用 filter 方法的例子,返回了一个包含了 30 岁以下的用户新数组。 为了简化,例子里只使用了回调函数的第一个参数。

const users = [
  { name: 'John', age: 34 },
  { name: 'Amy', age: 20 },
  { name: 'camperCat', age: 10 }
];

const usersUnder30 = users.filter(user => user.age < 30);
console.log(usersUnder30); 
控制台将显示值 [ { name: 'Amy', age: 20 }, { name: 'camperCat', age: 10 } ]

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

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

reduce()(即Array.prototype.reduce()),是 JavaScript 所有数组操作中最常用的方法。 几乎可以用reduce方法解决所有数组处理问题
回调函数接受四个参数。 第一个参数称为叠加器,它是上一次迭代中回调函数的返回值,第二个参数是当前正在处理的数组元素,第三个参数是该参数的索引,第四个参数是在其上调用 reduce 方法的数组。
除了回调函数,reduce 还有一个额外的参数做为叠加器的初始值。 如果没有第二个参数,会跳过第一次迭代,第二次迭代给叠加器传入数组的第一个元素。

例子,算平均数的,题目网站去看

function getRating(watchList){
  let n = 0;
  var averageRating = watchList.reduce(
    function(num,letim,i,tab){
      if(letim.Director == "Christopher Nolan"){
         num += Number(letim.imdbRating);
         n++;
      }
      if(i==tab.length-1) return num/n;   //这里表示最后一次循环,整除算了
      return num;
    },0)
  return averageRating;
}

第二种样式

function getRating(watchList){
  var averageRating = watchList.reduce(
    function(obj,letim,i,tab){
      if(i==0){
        obj.num = 0;
        obj.n = 0;
      }
      if(letim.Director == "Christopher Nolan"){
         obj.num += Number(letim.imdbRating);
         obj.n++;
      }
      if(i==tab.length-1) return obj.num/obj.n;   //这里表示最后一次循环,整除算了
      return obj;
    },{})
  return averageRating;
}
console.log(getRating(watchList));

使用高阶函数 map、filter 或者 reduce 来解决复杂问题
已经接触了高阶函数如 map()、 filter() 和 reduce()的使用,是时候用它们来完成一些复杂的挑战了。
使用 map()、filter() 和 reduce() 的任何组合完成 squareList 函数的代码。 传递一个包含实数的数组给函数时,函数应返回一个新的数组,只包含正整数(小数不是整数)的平方值, 例如 [-3, 4.8, 5, 3, -3.2] 这样一个包含实数的数组。
例子
const squareList = arr => arr.filter(item=>item>0&& item%parseInt(item) === 0).map(item=>item*item);
const squaredIntegers = squareList([-3, 4.8, 5, 3, -3.2]);
console.log(squaredIntegers);

数组按字母升序排序
function alphabeticalOrder(arr) {
   return arr.sort(function(a, b) {
    return a === b ? 0 : a < b ? -1 : 1;
  });
}

文字分割及合成例子
在函数 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片段
填写 urlSlug 函数,将字符串 title 转换成带有连字符号的 URL。 您可以使用本节中介绍的任何方法,但不要用 replace 方法。 以下是本次挑战的要求:
输入包含空格和标题大小写单词的字符串
输出字符串,单词之间的空格用连字符 (-) 替换
输出应该是小写字母
输出不应有任何空格
function urlSlug(title) {
 return title.split(/\s/).filter(val => val!="").join('-').toLowerCase();
}

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

如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测

举个例子,下面的代码检测数组 numbers 的所有元素是否都小于 10:
var numbers = [1, 5, 8, 0, 10, 11];
numbers.every(function(currentValue) {
  return currentValue < 10;
});
every 方法在这里会返回 false。
使用 some 方法检查数组中是否有元素是否符合条件
some 方法用于检测数组中任何元素是否满足指定条件。 如果有一个元素满足条件,返回布尔值 true,反之返回 false。
和上面的every使用方法相对于

函数柯里化和局部调用
function add(x) {
    return function(y){
       return function(z){
          return x+z+y;
       }
    }
}
console.log(add(10)(20)(30));

来说两句吧