js基础--数组方法

  • join()

Array.join()方法将数组中所有元素都转化为字符串并连接在一起,返回最后生成的字符串。可以指定一个可选
的字符串在生成的字符串中来分隔数组的各个元素。如果不指定分隔符,默认使用逗号。如以下代码所示:

var a=[1,2,3];//创建一个包含三个元素的数组
a.join();//=>"1,2,3"
a.join("");//=>"1 2 3"
a.join("");//=>"123"
var b=new Array(10);//长度为10的空数组
b.join('-')//=>'---------':9个连字号组成的字符串

Array.join()方法是String.split()方法的逆向操作,后者是将字符串分割成若干块来创建一个数组。
  • reverse()

Array.reverse()方法将数组中的元素颠倒顺序,返回逆序的数组。它采取了替换,换句
话说,它不通过重新排列的元素创建新的数组,而是在原先的数组中重新排列它们。例
如,下面的代码使用reverse()和join()方法生成字符串“3, 2, 1” ;

var a = [1,2,3];
a. reverse(). join() //=〉” 3,2,1 ”,并且现在的a是[ 3,2,1]
  • sort()

Array.sort()方法将数组中的元素排序并返回排序后的数组。当不带参数调用sort()时,数组元素以字母表顺序
排序(如有必要将临时转化为字符串进行比较):

var a=new Array("banana","cherry","apple");
a.sort();
var s=a.join(",");//s=="apple,banana,cherry"

如果数组包含undefined元素,它们会被排到数组的尾部。

为了按照其他方式而非字母表顺序进行数组排序,必须给sort()方法传递一个比较函数。该函数决定了它的两个
参数在排好序的数组中的先后顺序。假设第一个参数应该在前,比较函数应该返回一个小于0的数值。反之,假设
第一个参数应该在后,函数应该返回一个大于0的数值。并且,假设两个值相等(也就是说,它们的顺序无关紧
要),函数应该返回0。因此,例如,用数值大小而非字母表顺序进行数组排序,代码如下:

var a=[33,4,1111,222];
a.sort();//字母表顺序:1111,222,33,4
a.sort(function(a,b){//数值顺序:4,33,222,1111
return a-b;//根据顺序,返回负数、0、正数
});
a.sort(function(a,b){return b-a});//数值大小相反的顺序

注意,这里使用匿名函数表达式非常方便。既然比较函数只使用一次,就没必要给它们命名了。


另外一个数组元素排序的例子,也许需要对一个字符串数组执行不区分大小写的字母表排序,比较函数首先将参数
都转化为小写字符串(使用toLowercase()方法),再开始比较:

a = ['ant', 'Bug', 'cat', 'Dog']
a.sort(); //区分大小写的排序: [’ Bug', 'Dog ’,’ant' ,cat']

a.sort(function(s,t) { //不区分大小写的排序
var b = a.map(function(s) { return s.toLowerCase();})//不能直接使s.toLowerCase(),需要转换
var c= a.map(function(t) { return t.toLowerCase();})
if (c < b) return -1;
if (c > b) return 1;
return 0;
});        
//=> ['ant ',’ Bug ',’cat ',’Dog']
  • concat()

Array.concat()方法创建井返回一个新数组,它的元素包括调用concat()的原始数组的元素和concat()的每
个参数。如果这些参数中的任何一个自身是数组,则连接的是数组的元素,而非数组本身。但要注意,concat()
不会递归扁平化数组的数组。concat()也不会修改调用的数组。下面有一些示例:

var a = [1,2,3];
a.concat(4, 5);返回//[ 1,2,3,4,5]
a.concat ([ 4, 5]);//返回[ 1,2,3,4,5]
a.concat([4,5], [6, 7]);//返回[1,2,3,4,5,6,7]
a.concat ( 4, [ 5, [ 6, 7]]);//返回[ 1,2,3,4,5,[6,7]],不会递归扁平化数组的数组
  • slice()


Array.slice()方法返回指定数组的一个片段或子数组。它的两个参数分别指定了片段的开始和结束的位置。返回
的数组包含第一个参数指定的位置和所有到但不含第二个参数指定的位置之间的所有数组元素。如果只指定一个参
数,返回的数组将包含从开始位置到数组结尾的所有元素。如参数中出现负数,它表示相对于数组中最后一个元素
的位置。例如,参数-1指定了最后一个元素,而-3指定了倒数第三个元素。注意,slice()不会修改调用的数组。
下面有一些示例:

var a=[1,2,3,4,5];
a.slice(0,3);//返回[1,2,3]
a.slice(3);//返回[4,5]
a.slice(1,-1);//返回[2,3,4]
a.slice(-3,-2);//返回[3]
  • splice()

Array.splice()方法是在数组中插入或删除元素的通用方法。不同于slice()和concat(),splice()会修改调
用的数组。注意,splice()和slice()拥有非常相似的名字,但它们的功能却有本质的区别。

splice()能够从数组中删除元素、插入元素到数组中或者同时完成这两种操作。在插入或删除点之后的数组元素
会根据需要增加或减小它们的索引值,因此数组的其他部分仍然保持连续的。splice()的第一个参数指定了插入
和(或)删除的起始位置。第二个参数指定了应该从数组中删除的元素的个数。如果省略第二个参数,从起始点开
始到数组结尾的所有元素都将被删除。splice()返回一个由删除元素组成的数组,或者如果没有删除元素就返回
一个空数组。例如:

var a=[1,2,3,4,5,6,7,8];
a.splice(4);//返回[5,6,7,8];a是[1,2,3,4]
a.splice(1,2);//返回[2,3];a是[1,4]
a.splice(1,1);//返回[4];a是[1]

splice()的前两个参数指定了需要删除的数组元素。紧随其后的任意个数的参数指定了需要插入到数组中的元
素,从第一个参数指定的位置开始插入。例如:

var a=[1,2,3,4,5];
a.splice(2,0,'a','b');//返回[];a是[1,2,'a','b',3,4,5]
a.splice(2,2,[1,2],3);//返回['a','b'];a是[1,2,[1,2],3,3,4,5]

注意,区别于concat(),splice()会插入数组本身而非数组的元素。
  • push ()和pop()

push()和pop()方法允许将数组当做栈来使用。push()方法在数组的尾部添加一个或多个元素,并返回数组新的
长度。pop()方法则相反:它删除数组的最后一个元素,减小数组长度并返回它删除的值。注意,两个方法都修改
并替换原始数组而非生成一个修改版的新数组。组合使用push()和pop()能够用JavaScript数组实现先进后出的
栈。例如:

var stack=[];//stack:[]
stack.push(1,2);//stack:[1,2] 返回2
stack.pop();//stack:[1] 返回2
stack.push(3);//stack:[1,3] 返回2
stack.pop();//stack:[1] 返回3
stack.push([4,5]);//stack:[1,[4,5]] 返回2
stack.pop()//stack:[1] 返回[4,5]
stack.pop();//stack:[] 返回1
  • unshift ()和shift()


unshift()和shift()方法的行为非常类似于push()和pop(),不一样的是前者是在数组的头部而非尾部进行元素的插入和删除操作。
unshift()在数组的头部添加一个或多个元素,并将已存在的元素移动到更高索引的位置来获得足够的空间,最后返回数组新的长度。
shift()删除数组的第一个元素并将其返回,然后把所有随后的元素下移一个位置来填补数组头部的空缺。例如:

var a=[];//a:[]
a.unshift(1);//a:[1]返回:1
a.unshift(22);//a:[22,1]返回:2
a.shift();//a:[1]返回:22
a.unshift(3,[4,5]);//a:[3,[4,5],1]返回:3
a.shift();//a:[[4,5],1]返回:3
a.shift();//a:[1]返回:[4,5]
a.shift();//a:[]返回:1

注意,当使用多个参数调用unshift()时。参数是一次性插入的(就像splice()方法)而非一次一个地插入。这
意味着最终的数组中插入的元素的顺序和它们在参数列表中的顺序一致。而假如元素是一次一个地插入,它们的顺序应该是反过来的。
  • toString ()和tolocaleString()

数组和其他JavaScript对象一样拥有toString()方法。针对数组,该方法将其每个元素转化为字符串(如有必要
将调用元素的toString()方法)\并且输出用逗号分隔的字符串列表。注意,输出不包括方括号或其他任何形式的
包裹数组值的分隔符。例如:

[1,2,3].toString()//生成'1,2,3'
["a","b","c"].toString()//生成'a,b,c'
[1,[2,'c']].toString()//生成'1,2,c'

注意,这里与不使用任何参数调用join()方法返回的字符串是一样的。
toLocaleString()是toString()方法的本地化版本。它调用元素的toLocaleString()方法将每个数组元素转化
为字符串,并且使用本地化(和自定义实现的)分隔符将这些字符串连接起来生成最终的字符串。

 

ECMAScript 5中的数组方法

ECMAScript 5定义了9个新的数组方法来遍历、映射、过滤、检测、简化和搜索数组。

      首先,大多数方法的第一个参数接收一个函数,并且对数组的每个元素(或一些元素)调用一次该函数。如果是稀疏数组,对不存在的元素不调用传递的函数。在大多数情况下,调用提供的函数使用三个参数:数组元素、元素的索引和数组本身。通常,只需要第一个参数值,可以忽略后两个参数。大多数ECMAScript 5数组方法的第一个参数是一个函数,第二个参数是可选的。如果有第二个参数,则调用的函数被看做是第二个参数的方法。也就是说,在调用函数时传递进去的第二个参数作为它的this关键字的值来使用。被调用的函数的返回值非常重要,但是不同的方法处理返回值的方式也不一样。ECMAScript 5中的数组方法都不会修改它们调用的原始数组。当然,传递给这些方法的函数是可以修改这些数组的。

  • forEach()

forEach()方法从头至尾遍历数组,为每个元素调用指定的函数。如上所述,传递的函数作为forEach()的第一个
参数。然后forEach()使用三个参数调用该函数:数组元素、元素的索引和数组本身。如果只关心数组元素的值,
可以编写只有一个参数的函数——额外的参数将忽略:

var data=[1,2,3,4,5];//要求和的数组
//计算数组元素的和值
var sum=0;//初始为0
data.forEach(function(value){sum+=value;});//将每个值累加到sum上
sum//=>15//每个数组元素的值自加1
data.forEach(function(v,i,a){a[i]=v+1;});
data//=>[2,3,4,5,6]

注意,forEach()无法在所有元素都传递给调用的函数之前终止遍历。也就是说,没有像for循环中使用的相应的
break语句。如果要提前终止,必须把forEach()方法放在一个try块中,并能抛出一个异常。如果forEach()调
用的函数抛出foreach.break异常,循环会提前终止:

function foreach(a,f,t){
    try{a.forEach(f,t);}
    catch(e){
        if(e===foreach.break)return;
        else throw e;
    }
}
foreach.break=new Error("StopIteration");
  • map()

map()方法将调用的数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数的返回值。例如:

a=[1,2,3];
b=a.map(function(x){return x*x;});//b是[1,4,9]

传递给map()的函数的调用方式和传递给forEach()的函数的调用方式一样。但传递给map()的函数应该有返回
值。注意,map()返回的是新数组:它不修改调用的数组。如果是稀疏数组,返回的也是相同方式的稀疏数组:它
具有相同的长度,相同的缺失元素。
  • filter()

fliter()方法返回的数组元素是调用的数组的一个子集。传递的函数是用来逻辑判定的:该函数返回true或
false。调用判定函数就像调用forEach()和map()一样。如果返回值为true或能转化为true的值,那么传递给判
定函数的元素就是这个子集的成员,它将被添加到一个作为返回值的数组中。例如:

a=[5,4,3,2,1];
smallvalues=a.filter(function(x){return x<3});//[2,1]
everyother=a.filter(function(x,i){return i%2==0});//[5,3,1]

注意,filter()会跳过稀疏数组中缺少的元素,它的返回数组总是稠密的。为了压缩稀疏数组的空缺,代码如下:

var dense=sparse.filter(function(){return true;});

甚至,压缩空缺并删除undefined和null元素,可以这样使用filter():

a=a.filter(function(x){return x!==undefined&&x!=null;});
  • every()和some()

every()和some()方法是数组的逻辑判定:它们对数组元素应用指定的函数进行判定,返回true或false。

every()方法就像数学中的“针对所有”的量词:当且仅当针对数组中的所有元素调用判定函数都返回true,它才返
回true:

a=[1,2,3,4,5];
a.every(function(x){return x<10;})//=>true:所有的值<10
a.every(function(x){return x%2===0;})//=>false:不是所有的值都是偶数

some()方法就像数学中的“存在”的量词:当数组中至少有一个元素调用判定函数返回true,它就返回true;并且
当且仅当数值中的所有元素调用判定函数都返回false,它才返回false:

a=[1,2,3,4,5];
a.some(function(x){return x%2===0;})//=>true:a含有偶数值
a.some(isNaN)//=>false:a不包含非数值元素

注意,一旦every()和some()确认该返回什么值它们就会停止遍历数组元素。some()在判定函数第一次返回true
后就返回true,但如果判定函数一直返回false,它将会遍历整个数组。every()恰好相反:它在判定函数第一次
返回false后就返回false,但如果判定函数一直返回true,它将会遍历整个数组。注意,根据数学上的惯例,在
空数组上调用时,every()返回true,some()返回false。
  • reduce()和reduceRight()

reduce()和reduceRight()方法使用指定的函数将数组元素进行组合,生成单个值。这在函数式编程中是常见
的操作,也可以称为“注入”和“折叠”。举例说明它是如何工作的:

var a=[1,2,3,4,5]
var sum=a.reduce(function(x,y){return x+y},0);//数组求和
var product=a.reduce(function(x,y){return x*y},1);//数组求积
var max=a.reduce(function(x,y){return(x>y)?x:y;});//求最大值

reduce()需要两个参数。第一个是执行化简操作的函数。化简函数的任务就是用某种方法把两个值组合或化简
为一个值,并返回化简后的值。在上述例子中,函数通过加法、乘法或取最大值的方法组合两个值。第二个
(可选)的参数是一个传递给函数的初始值。

reduce()使用的函数与forEach()和map()使用的函数不同。比较熟悉的是,数组元素、元素的索引和数组本
身将作为第2~4个参数传递给函数。第一个参数是到目前为止的化简操作累积的结果。第一次调用函数时,第
一个参数是一个初始值,它就是传递给reduce()的第二个参数。在接下来的调用中,这个值就是上一次化简函
数的返回值。在上面的第一个例子中,第一次调用化简函数时的参数是0和1。将两者相加并返回1。再次调用时
的参数是1和2,它返回3。然后它计算3+3=6、6+4=10,最后计算10+5=15。最后的值是15,reduce()返回这
个值。

可能已经注意到了,上面第三次调用reduce()时只有一个参数:没有指定初始值。当不指定初始值调用
reduce()时,它将使用数组的第一个元素作为其初始值。这意味着第一次调用化简函数就使用了第一个和第二
个数组元素作为其第一个和第二个参数。在上面求和与求积的例子中,可以省略初始值参数。

在空数组上,不带初始值参数调用reduce()将导致类型错误异常。如果调用它的时候只有一个值——数组只有一
个元素并且没有指定初始值,或者有一个空数组并且指定一个初始值——reduce()只是简单地返回那个值而不会
调用化简函数。

reduceRight()的工作原理和reduce()一样,不同的是它按照数组索引从高到低(从右到左)处理数组,而不
是从低到高。如果化简操作的优先顺序是从右到左,你可能想使用它,例如:

var a=[2,3,4]//计算2^(3^4)。乘方操作的优先顺序是从右到左
var big=a.reduceRight(function(accumulator,value){
    return Math.pow(value,accumulator);
});


注意,reduce()和reduceRight()都能接收一个可选的参数,它指定了化简函数调用时的this关键字的值。可
选的初始值参数仍然需要占一个位置。如果想让化简函数作为一个特殊对象的方法调用,请参看
Function.bind()方法。

值得注意的是,上面描述的every()和some()方法是一种类型的数组化简操作。但是不同的是,它们会尽早终
止遍历而不总是访问每一个数组元素。

为了简单起见,到目前位置所展示的例子都是数值的,但数学计算不是reduce()和reduceRight()的唯一意
图。它计算两个对象的“并集”,并返回另一个新对象,新对象具有二者的属性。该函数期待两个对象并返回另
一个对象,所以它的工作原理和一个化简函数一样,并且可以使用reduce()来把它一般化,计算任意数目的对
象的“并集”。

var objects=[{x:1},{y:2},{z:3}];
var merged=objects.reduce(union);//=>{x:1,y:2,z:3}

回想一下,当两个对象拥有同名的属性时,union()函数使用第一个参数的属性值。这样,reduce()和
reduceRight()在使用union()时给出了不同的结果:

var objects=[{x:1,a:1},{y:2,a:2},{z:3,a:3}];
var leftunion=objects.reduce(union);//{x:1,y:2,z:3,a:1}
var rightunion=objects.reduceRight(union);//{x:1,y:2,z:3,a:3}
  • indexOf()和lastIndexOf()

indexOf()和lastIndexOf()搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引或者如果没有找到
就返回-1。indexOf()从头至尾搜索,而lastIndexOf()则反向搜索。

a=[0,1,2,1,0];
a.indexOf(1)//=>1:a[1]是1
a.lastIndexOf(1)//=>3:a[3]是1
a.indexOf(3)//=>-1:没有值为3的元素

不同于本节描述的其他方法,indexOf()和lastIndexOf()方法不接收一个函数作为其参数。第一个参数是需要搜
索的值,第二个参数是可选的:它指定数组中的一个索引,从那里开始搜索。如果省略该参数,indexOf()从头开
始搜索,而lastIndexOf()从末尾开始搜索。第二个参数也可以是负数,它代表相对数组末尾的偏移量,对于
splice()方法:例如,-1指定数组的最后一个元素。

如下函数在一个数组中搜索指定的值并返回包含所有匹配的数组索引的一个数组。它展示了如何运用indexOf()的
第二个参数来查找除了第一个以外匹配的值。

//在数组中查找所有出现的x,并返回一个包含匹配索引的数组
function findall(a,x){
    var results=[],//将会返回的数组
        len=a.length,//待搜索数组的长度
        pos=0;//开始搜索的位置
    while(pos<len){//循环搜索多个元素...
        pos=a.indexOf(x,pos);//搜索
        if(pos===-1)break;//未找到,就完成搜索
        results.push(pos);//否则,在数组中存储索引
        pos=pos+1;//并从下一个位置开始搜索
    }
    return results;//返回包含索引的数组
}

注意,字符串也有indexOf()和lastIndexOf()方法,它们和数组方法的功能类似。

猜你喜欢

转载自blog.csdn.net/wuyufa1994/article/details/85200017