JavaScript中关于数组的内容

数组中常用的方法

  • 方法的作用和含义
  • 方法的实参(类型和含义)
  • 方法的返回值
  • 原来的数组是否发生改变

1.实现数组增删改的方法

这一部分的方法都会改变原有的数组

push

push:向数组末尾增加内容

参数:多个任意类型

返回值:新增后数组的长度

let arr = [10,20];
let res = arr.push(30,'aa');
// 基于原生js操作键值对的方法,也可以实现向数组末尾增加一项新的内容
arr[arr.length] = 40;
console.log(res,arr); //=> 4, [10,20,30,'aa',40]

unshift

unshift: 向数组开始位置增加内容

参数: 多个任意类型

返回值: 新增数组长度

let ary = [10,20];
let res = ary.unshift(30,'AA');
console.log(res,ary); //=>4 [30,'AA',10,20]
// 基于原生ES6展开运算符,把原有的ARY克隆一份,再新的数组中创建第一项,其余内容使用原始ARY中的信息即可,也算实现了向开始追加的效果
ary = [100,...ary];
console.log(ary); //=>[100,30,'AA',10,20]

shift

shift: 删除数组中的第一项

参数: 无

返回值:删除的那一项

let ary = [10,20,30,40];
let res = ary.shift();
console.log(res,ary); //=> 10 [20,30,40]

// 基于原生js中的delete,把数组当作普通对象,确实可以删除掉某项一项的内容,但是不会影响数组本身的结构特点(length长度不会跟着修改),真实项目中杜绝这样使用
/*delete ary[0];
console.log(ary); //=> {1:30,2:40,length:3}  */

pop

pop: 删除数组中的最后一项

参数:无

返回值: 删除的那一项

let ary = [10,20,30,40];
let res = ary.pop();
console.log(res,ary); // 40 [10,20,30]

// 基于原生js让数组的数组长度干掉一位,默认干掉的就是最后一项
ary.length--;
console.log(ary); //=> [10,20]

splice

splice:实现数组的增加,删除,修改

参数:n,m(都是数字) 从索引n开始,删除m个元素(m不写,是删除到末尾);

​ n,m,x 从索引n开始删除m个元素,用x占用删除的部分

​ n,0,x 从索引n开始,一个都不删,把x放到索引n的前面

返回值:把删除的部分用新数组存储起来返回

let ary = [10,20,30,40,50,60,70,80,90];
let res = ary.splice(2,4);
console.log(res,ary); //=> [30,40,50,60] [10,20,70,80,90]

/*
res = ary.splice(0);
// 基于这种方法可以清空一个数组,把原始数组中的内容以新数组存储起来(有点类似数组克隆;把原来数组克隆一份一模一样的数组给新数组)
console.log(res,ary); //=> [10,20,70,80,90]
*/

// 删除最后一项
ary.splice(ary.length - 1);
console.log(ary); // [20,70,80,90]
// 删除第一项
ary.splice(0,1);
console.log(ary); // [70,80,90]
let ary = [10,20,30,40,50];
let res = arr.splice(1,2,'好好学习''天天向上');
console.log(res,ary); //=> [20,30] [10,'好好学习','天天向上',40,50]

// 实现增加
ary.splice(3,0,'HelloWorld');
console.log(ary); //=> [10,'好好学习','天天向上','HelloWorld',40,50]

// 向数组末尾追加
ary.splice(ary.length,0,'AAA');
console.log(ary); //=>[10,'好好学习','天天向上','HelloWorld',40,50,'AAA']

// 向数组开始追加
arr.splice(0,0,'BBB');
console.log(ary); //=>['BBB',10,'好好学习','天天向上','HelloWorld',40,50,'AAA']

2.数组的查询和拼接

此组方法中,原数组不会改变

slice

slice: 实现数组的查询

参数:n,m 都是数字 从索引n开始,找到索引m的地方(不包含m这一项)包左不包右

返回值:把找到的内容以一个新数组的形式返回

let ary = [10,20,30,40,50];
let res = ary.slice(1,3);
consloe.log(res); //=> [20,30]

// m不写是找到末尾
res = ary.slice(1);
console.log(res); //=> [20,30,40,50]

// 数组的克隆,参数0不写也可以
res = ary.slice(0);
console.log(res); //=> [10,20,30,40,50]


思考

  1. 如果n/m为负数会发生啥
  2. n>m会发生啥
  3. 如果是小数会发生啥
  4. 如果是非有效数字会发生啥
  5. 如果m或者n的值比最大索引都大会发生啥
  6. 这种方法也叫浅克隆,深克隆是什么?
// 当只有一个参数n时,n为负数,会将负的参数加上数组的长度
let ary = [10,20,30,40,50];
let res = ary.slice(-3); //=> 相当于ary.slice(5+(-3))
console.log(res); //=> [30,40,50]

// 当有两个参数n,m时,第一个参数和第二个参数如果为负的,就都先加上数组的长度,关键在于加完后的第一个参数start应该比第二个参数end小,否则取不到东西,返回则为空。
let res1 = ary.slice(-1,3);  //=> 相当于ary.slice((-1)+5,3) => ary.slice(4,3)
let res2 = ary.slice(-1,-3); //=> 相当于ary.slice((-1)+5,(-3)+5) => ary.slice(4,2)
let res3 = ary.slice(-3,-1); //=> 相当于ary.slice((-3)+5,(-1)+5) => ary.slice(2,4)
let res4 = ary.slice(-3,3); //=> 相当于ary.slice((-3)+5,3) => ary.slice(2,3)
let res5 = ary.slice(1,-3);  //=> 相当于ary.slice(1,5+(-3)) => ary.slice(1,2)
console.log(res1);  //=> []
console.log(res2);  //=> []
console.log(res3);  //=> [30,40]
console.log(res4);  //=> [30]
console.log(res5);  //=> [20]
// 当第一个参数n比第二个参数m大时,如果两个参数全是正数,则全返回空数组[];如果是n是正数而m为负数,则根据具体情况分析
let ary = [10,20,30,40,50];
let res1 = ary.slice(4,2);
console.log(res1); //=> []
let res2 = ary.slice(1,-3);  //=> 相当于ary.slice(1,5+(-3)) => ary.slice(1,2)
console.log(res2);  //=> [20]
// 如果两个参数m,n都为小数,如果参数为正数,则向下取整;如果为参数负数,则向上取整
let ary = [10,20,30,40,50];
let res1 = ary.slice(1.1,4.9); //=> ary.slice(1,4)
console.log(res1);  //=> [20, 30, 40]
let res2 = ary.slice(1.1,6.4); //=> ary.slice(1,6)
console.log(res2);  //=> [20, 30, 40, 50]
let res3 = ary.slice(-2.9,5); //=>ary.slice(-2,5)=>ary.slice((-2)+5,5)=>ary.slice(3,5)
console.log(res3); //=> [40,50]
// 当两个参数不是有效数字时,如果两个参数为字符串,会将字符串先通过Number()转换为数字,再执行方法;否则,返回空数组[]
let ary = [10,20,30,40,50];
let res1 = ary.slice("1","-3"); //=> ary.slice(1,-3)
console.log(res1); //=> [20]
let res2 = ary.slice("Hello","World");
console.log(res2); //=> []
// 当两个参数都比索引大时,返回结果为空数组
let ary = [10,20,30,40,50];
let res1 = ary.slice(6,7);
let res2 = ary.slice(7,6);
console.log(res1); //=> []
console.log(res2); //=> []

concat

concat : 实现数组拼接

参数:多个任意类型值

返回值: 拼接后的新数组(原数组不变)

let ary1 = [10,20,30];
let ary2 = [40,50,60];
let res = ary1.concat('day,day,up!',ary2);
console.log(res); //=> [10,20,30,'day,day,up!',40,50,60]

3.把数组转换为字符串

原有数组不变

toString

toString : 把数组转换为字符串

参数:无

返回值:转换后的字符串(原来的数组不变)

let ary = [10,20,30];
let res = ary.toString();
console.log(res); //=> "10,20,30"
console.log([].toString()); //=> ""
console.log([12].toString()); //=> "12"

join

join: 把数组转换为字符串

参数:指定的分隔符(字符串格式)

返回值:转换后的字符串(原数组不变)

let ary = [10,20,30];

let res = ary.join('');
console.log(res); //=>"102030"

res = ary.join();
console.log(res); //=>"10,20,30"

res = ary.join("|");
console.log(res); //=>"10|20|30"

res = ary.join('+');
console.log(res); //=> "10+20+30"
console.log(eval(res));  //=>60  eval把字符串变为JS表达式

4.检测数组中是否包含某一项

indexOf / lastIndexOf / includes

indexOf / lastIndexOf:检测当前项在数组中第一次或者最后一次出现位置的索引值(在IE6~8中不兼容)

参数:要检索的这一项内容

返回值:这一项出现的位置索引值(数字),如果数组中没有这一项,返回值的结果是-1, 原数组不变

 let ary = [10, 20, 30, 10, 20, 30];
 console.log(ary.indexOf(20)); //=>1
 console.log(ary.lastIndexOf(20)); //=>4

// 想验证ary中是否包含'40'
if (ary.indexOf('40') === -1) {
	//不包含
	console.log("不包含");
}
// 也可以直接使用ES6新提供的includes方法判断
if (ary.includes('40')) {
	// 包含:如果存在返回的是true
	console.log("包含");
}

5.数组的排序或排列

reverse

reverse: 把数组倒过来排列

参数:无

返回值:排列后的新数组,原来数组改变

let ary = [12,15,9,28,10,22];
ary.reverse();
console.log(ary); //=> [22,10,28,9,15,12]

sort

sort: 实现数组的排序

参数:arr.sort([compareFunction])

compareFunction 可选

​ 用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点 进行排序。

  • firstEl

    第一个用于比较的元素。

  • secondEl

    第二个用于比较的元素。

返回值:排序后的新数组,原来的数组改变

let ary1 = [7,8,5,2,4,6,9];
ary.sort();
console.log(ary1); //=>[2,4,5,6,7,8,9]

// sort方法中如果不传参数,是无法处理10以上的数字排序的(它默认按照每一项第一个字符来排)
let ary2 = [12,15,9,28,10,22];
ary.sort();
console.log(ary2); //=> [10,12,15,22,28,9]

如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。例如 “Banana” 会被排列到 “cherry” 之前。当数字按由小到大排序时,9应该出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在Unicode顺序上 “80” 要比 “9” 要靠前。

如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;

  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。

  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。

  • compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

// 所以,比较函数格式如下:
function compare(a, b) {
  if (a < b ) {           // 按某种排序标准进行比较, a 小于 b
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

要比较数字而非字符串,比较函数可以简单的以 a 减 b,如下的函数将会将数组升序排列

function compareNumbers(a, b) {
  return a - b;
}

sort 方法可以使用 函数表达式方便地书写:

var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
  return a - b;
});
console.log(numbers);

也可以写成:
var numbers = [4, 2, 5, 1, 3]; 
numbers.sort((a, b) => a - b); 
console.log(numbers);

// [1, 2, 3, 4, 5]

6.遍历数组的每一项的方法

forEach

forEach:遍历数组中的每一项内容

参数: 回调函数

返回值:无 原数组不变

let ary = [12,15,9,28,10,22];

// 基于原生js中的循环可以实现
	for (let i = 0;i < ary.length;i++) {
		// i:当前循环这一项的索引
		// ary[i]:根据索引获取循环的这一项
		console.log('索引'+i+'内容'+ary[i]);
	}
// forEach()实现
ary.forEach((item,index) => {
    // 数组中有多少项,函数就会被默认执行多少次
    // 每一次执行函数:item是数组中当前要操作的这一项,index是当前项的索引
    console.log('索引'+index+'内容'+item);
});

map

filter

find

reduce

some

every

7.数组去重的方法

方案一

    let ary = [1,2,3,1,2,3,1,2,3];
    /*循环原有的数组中的每一项,添加到空数组中,每次添加的时候验证一下,新数组中是否已经存在这一项,不存在再增加 */
    let newAry = [];
    for (let i = 0; i < ary.length; i++) {
        // 循环获取原数组中的每一项
        let item = ary[i];
        // 验证新数组中是否存在这一项
        if (newAry.includes(item)) {
            // 存在这一项,不在增加到新数组中,继续下一轮循环即可
            continue;
        }
        // 新数组中不存在这一项,我们加入到新数组中即可
        newAry.push(item);
    }
    console.log(newAry);
// 上述代码的优化
let ary = [1,2,3,1,2,3,1,2,3];
let newAry = [];
ary.forEach(item => {
    if(newAry.includes(item)) return;
    newAry.push(item);
});
console.log(newAry);

方案二

// 循环原来数组的每一项,每一次拿出来的值都跟它后边的值进行比较
// 比较的过程中遇到与自己相同的,把这一项从数组中删除=> splice
let ary = [1, 2, 3, 1, 2, 3, 1, 2, 3];
for (let i = 0; i < ary.length; i++) {
    // item: 每次拿出来的当前项
    // i:当前项的索引 i+1:代表后一项
    let item = ary[i];
    // 让当前项和后面的每一项进行比较(循环)
    for (let j = i + 1; j < ary.length; j++) {
        // compare:后面拿出来要比较的一项
        let compare = ary[j];
        // 如果compare和item相等,说明这一项是重复的,我们把它删掉
        if (compare === item) {
            // j索引这一项要从数组中移除
            ary.splice(j, 1);
            /* 数组会发生塌陷:j后面的每一项索引都会提前一位,下次要比较的应该还是j这个索引的内容 */
            j--; // 所以每次将j--,防止循环后j++
        }
    }
}
console.log(ary);

方案三

// 基于对象的方法,优化
let ary = [1,2,3,1,2,3,1,2,3];
// 1.创建一个空对象
let obj = {};
// 2.循环数组中的每一项,把每一项向对象中进行存储 => item:item
for (let i = 0;i < ary.length;i++) {
    let item = ary[i];
    // 3.每一次存储之前进行判断;验证obj中是否存在这一项
    if (obj[item] !== undefined) {
        // 已存在这一项
        ary.splice(i,1);
        i--;
        continue;
    }
    obj[item] = item;
}
console.log(obj);

方案四

// 对方案三的优化
// 基于splice实现删除性能不好;当前项被删除后,后一项的索引都要向前提一位,如果后面内容过多,一定影响性能
let ary = [1,2,3,1,2,3,1,2,3];
let obj = {};
for (let i = 0;i < ary.length;i++) {
    let item = ary[i];
    if (obj[item] !== undefined) {
        ary[i] = ary[ary.length-1]; // 将最后一项的值给当前项
        ary.length--; // 数组长度减一,即可将数组最后一位删掉
        i--; // 由于原来的最后一项的值为当前项,因此还要与此项对比,为防止i++,进行i--
        continue;
    }
    obj[item] = item;
}
console.log(obj);

对此方案,创建数组去重的函数

unique:实现数组去重的方法

参数:要去重的数组

返回值:去重后的数组

function unique(ary) {
    let obj = {};
    for (let i = 0;i < ary.length;i++) {
        let item = ary[i];
        if (obj[item] !== undefined) {
            ary[i] = ary[ary.length-1]; 
            ary.length--;
            i--; 
            continue;
    	}
    	obj[item] = item;
	}
    return ary;
}

方案五

// 基于ES6的Set实现去重
let ary = [1,2,3,1,3,2,1,2,3];
ary = [...new Set(ary)];
console.log(ary);
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值