Javascript中数组方法和方法的扩展

时间:2022-03-08 19:02:59

1.数组实例方法的练习

  1.1:reduce()

  1.2:map()

  1.3:sort()

  1.4:slice()

  1.5:push()

  1.6:实例方法习题

2.数组方法的扩展

 

 

 

1.数组实例方法的练习

  首先,我们应该知道数组实例方法有哪些。

    console.log(Object.getOwnPropertyNames(Array));
// ["isArray", "concat", "lastIndexOf", "indexOf", "forEach", "map", "filter", "every", "some", "reduce", "reduceRight", "join", "reverse", "sort", "push", "pop", "shift", "unshift", "splice", "slice", "from", "of", "prototype", "length", "name"]

  上面代码中,使用对象的原生方法getOwnPropertyNames方法来返回对象实例的所有方法。

  下面对一些实例方法做一些简单的介绍。

  1.1:reduce方法

  reduce方法和reduceRight方法都是依次处理数组的每个成员,最终累计为一个值。它们的差别是,reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员),其他完全一样。

  这两个方法的第一个参数都是一个函数。该函数接受以下四个参数。

    累积变量,默认为数组的第一个成员

    当前变量,默认为数组的第二个成员

    当前位置(从0开始)

    原数组

  只有前两个才是必须传入的,reduce方法最常用的就是用于数组元素的相加,然后返回累加的值

1     var arr = [1,2,3,4,5];
2
3 function sum(first,last){
4 return first+last;
5 }
6
7 console.log(arr.reduce(sum)) //15

   针对reduce()方法,我重新写了一篇详细的文章,传送门:reduce()方法解析

  1.2:map()

  map方法对数组的所有成员依次调用一个函数,根据函数结果返回一个新数组。要注意的是,map方法返回一个新数组,而原数组是没有发生变化的。

1     var arr = [1,2,3,4,5];
2
3 var newArr = arr.map(function(value, index) {
4 return value+1;
5 });
6
7 console.log(newArr); // [2, 3, 4, 5, 6]
8 console.log(arr); // [1, 2, 3, 4, 5]

  上面代码中,arr数组的所有成员都加上1,组成一个新数组返回,原数组没有变化。

  map方法接受一个函数作为参数。该函数调用时,map方法会将其传入三个参数,分别是当前成员、当前位置和数组本身。

 

  1.3:sort()

  sort方法对数组成员进行排序,默认是按照ascii字母顺序排序。排序后,原数组将被改变

1     var arr1 = [5,6,7,2,6,8,1];
2 console.log(arr1.sort()); //[1, 2, 5, 6, 6, 7, 8]
3    console.log(arr1);    //[1, 2, 5, 6, 6, 7, 8]
4 var arr2 = [1,2,3,11,22,33];
5 console.log(arr2.sort()); //[1, 11, 2, 22, 3, 33]
6 console.log(arr2);      //[1, 11, 2, 22, 3, 33]

  如果要让sort方法正常排序,可以传入一个函数。函数带有两个参数,表示进行比较的两个元素。

    var arr2 = [1,2,3,11,22,33];
console.log(arr2.sort(
function(a,b){
return a - b;
}));
// [1, 2, 3, 11, 22, 33]

  

  1.4:slice()

  slice方法用于提取原数组的一部分,返回一个新数组,原数组不变。它的第一个参数为起始位置(从0开始),第二个参数为终止位置(但该位置的元素本身不包括在内)。如果省略第二个参数,则一直返回到原数组的最后一个成员。

1     var arr = [1,2,3,4,5];
2
3 console.log(arr.slice(0)); // [1, 2, 3, 4, 5]
4 console.log(arr.slice(1,2)); //[2]
5 console.log(arr.slice(2,5)); //[3, 4, 5]
6 console.log(arr.slice(3)); //[4, 5]
7 console.log(arr); //[1, 2, 3, 4, 5]

  如果slice为负数,则表示倒数计算的位置。

1     var arr = [1,2,3,4,5];
2
3 console.log(arr.slice(-3));//[3, 4, 5]
4 console.log(arr.slice(-3,-1));// [3, 4]
5 console.log(arr); // [1, 2, 3, 4, 5]

  注意,传入负数时,index值是从-1开始计算的。而传入正数时,index值是从0开始计算的。

 

  1.5:push()

  push方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组

    var arr = [1,2,3,4,5];

arr.push(
6);
console.log(arr);
// [1, 2, 3, 4, 5, 6]
arr.push([7,8]);
console.log(arr);
// [1, 2, 3, 4, 5, 6, [7, 8]]
arr.push(true);
console.log(arr);
// [1, 2, 3, 4, 5, 6, [7, 8], true]

 

  1.6:实例方法习题

  ★数组中去掉最大值,去掉最小值,其余元素进行相加。

    function sumArray(array) {
if (array === null || array.length < 2) {
return 0;
}
else {
array
= array.sort(function(a, b) {
return a - b;
})
var sum = 0;
for (var i = 1; i < array.length - 1; i++) {
sum
+= array[i];
}
return sum;
}
}

console.log(sumArray([
1,2,3,4,5,9])); //14

  上面代码中,使用了sort方法对数组进行排序。然后巧妙地使用for循环,让变量初始化的值等于第二个元素,让循环的长度值等于数组的长度减一,这样就实现了去掉一个最小值和最大值,剩余值进行相加的方法。

  ★将字符串中的元素分隔,首字符大写,然后再按照index值加入相同小写字母。比较难描述,看例子,就很容易理解。

 1     function accum(s) {
2 var arr = s.split('');
3 return arr.map(function(value, index) {
4 var upper = value.toUpperCase();
5 for (var i = 1; i <= index; i++) {
6 upper += value.toLowerCase();
7 }
8 return upper;
9 }).join('-')
10 }
11
12 console.log(accum('keith')); //'K-Ee-Iii-Tttt-Hhhhh'
13 console.log(accum('studyhard')); //'S-Tt-Uuu-Dddd-Yyyyy-Hhhhhh-Aaaaaaa-Rrrrrrrr-Ddddddddd'

  上面代码中,使用字符串对象的实例方法先将字符串分割,接着用map方法循环每一个字符。要注意的是map方法会返回一个新数组,不改变原数组,最后使用字符串对象实例方法join方法将字符串以'-'的形式分割。

  ★将平均数与个人成绩进行比较。如果大于平均数,则返回true;否则为false。

 1     function betterThanAverage(classPoints, yourPoints) {
2 var len=classPoints.length;
3 var sum=0;
4 for (var i = 0; i < classPoints.length; i++) {
5 sum+=classPoints[i];
6 }
7 if (yourPoints>(sum/len)) {
8 return true;
9 } else{
10 return false;
11 }
12 }
13
14 console.log(betterThanAverage([62,83,74,66,99,100],80)); //false

  上面代码中,先获取数组的长度,然后将数组进行相加,再除以长度值,最后进行比较。

  ★当数组中的数为正数时,计算正数的个数;当数组中的数为负数时,将所有负数相加。注意,对负数和正数的处理方式不同。

    function countPositivesSumNegatives(input) {
if (input===null||input.length===0) {
return [];
}
else{
var count = 0;
var sum = 0;
for(var i = 0;i < input.length; i++){
if (input[i]<0) {
sum
+=input[i];
}
else if(input[i]!==0){
count
+=1;
}
}
return [count,sum];
}
}

console.log(countPositivesSumNegatives([
1, 2, 3, 4, 5, 6, 7, 8, 9, 131,10, -11, -12, -13, -14, -15])); //[11, -65]

  上面代码中,对数组进行了简单的判断。使用for循环再对数组的正负值进行判断。

  ★创建一个函数,这个函数有2个参数,第一个参数为有x个值得数组,第二个参数为数组的长度。功能就是将最后x个值进行相加然后传入数组末尾。有两种解决方法,第二种方法采用了es6的方法箭头函数。同样,看实例比较容易理解题目的意思。

    function Sum(first,last){
return first+last;
}

function Xbonacci(signature,n){
var indexArr = signature.length;
for (var i = 0; i < n - indexArr; i++) {
var sum = signature.slice(-indexArr).reduce(Sum);
signature.push(sum);
}
return signature.slice(0,n);
}

console.log(Xbonacci([
0,0,0,0,1],10)); //[0, 0, 0, 0, 1, 1, 2, 4, 8, 16]
console.log(Xbonacci([1,1],10)); // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
console.log(Xbonacci([1,0,0,0,0,0,1],10)); // [1, 0, 0, 0, 0, 0, 1, 2, 3, 6]
console.log(Xbonacci([0, 19, 16, 3, 6, 14, 17, 14, 15, 20, 8, 19, 7, 8, 12, 14, 11, 11, 18],4)); // [0, 19, 16, 3]
    const Xbonacci = (sig, n) => {
let len
= sig.length;
for (let i = len; i < n; i++)
sig[i]
= sig.slice(i - len).reduce((a, b) => a + b);
return sig.slice(0, n);
}

  上面代码中,将[0,0,0,0,1]相加得2,然后将2push到数组中;将[0,0,0,1,2]相加4,然后将4push到数组中,以此类推。最后返回处理后的数组。

 

  个人认为,熟悉数组实例方法最好的办法就是去尝试做这些题目,每一次做的题目对数组的方法都会有一个新的理解,每一次理解都会让你意识到哪一个方法需要在哪一种场景使用,而哪一个方法在某个场景使用是不合适的。光看不练对知识的掌握程度总是稍显不足。

 

 

2.数组方法的扩展

  数组的实例方法中,没有给我们提供数组求和,求平方,求立方,求平均数,求偶数元素,求奇数元素的方法。所以我们需要去扩展数组的方法以方便实际工作中的开发。

    Array.prototype.square  = function () { return this.map(function(n) { return n*n; }); }
Array.prototype.cube
= function () { return this.map(function(n) { return n*n*n; }); }
Array.prototype.average
= function () { return this.sum() / this.length; }
Array.prototype.sum
= function () { return this.reduce(function(a, b) { return a + b; }, 0); }
Array.prototype.even
= function () { return this.filter(function(item) { return 0 === item % 2; }); }
Array.prototype.odd
= function () { return this.filter(function(item) { return 0 !== item % 2; }); }

var arr = [1,2,3,4,5,6];

console.log(arr.square());
// [1, 4, 9, 16, 25, 36]
console.log(arr.cube()); // [1, 8, 27, 64, 125, 216]
console.log(arr.average()); // 3.5
console.log(arr.sum()); // 21
console.log(arr.even()); // [2, 4, 6]
console.log(arr.odd()); // [1, 3, 5]

  上面代码中,为构造函数Array的原型对象添加square,cube等方法的目的是让所有实例都可以共享这些方法。而prototype属性的作用也就是让所有实例对象可以共享属性和方法。  

  如果想理解数组方法的扩展,需要知道的知识有:

  1.原型对象和构造函数的关系。

  2.this关键字的指向性问题。

  如果想要详细了解,可以前往这这些文章。Javascript中prototype属性的详解javascript之 this 关键字详解Javascript 中构造函数与new命令的密切关系深入理解Javascript中构造函数和原型对象的区别 等。

 

  

 

 

完。

 

 

感谢大家的阅读。

转载请注明出处:http://www.cnblogs.com/Uncle-Keith/p/5846576.html