Js中forEach修改原数组与sort排序经典场景详解

目录
  • forEach() 介绍
  • forEach() 能不能改变原数组?
  • sort() 介绍
    • 如果在使用 sort() 方法时不带参,
    • sort()方法:带参时,自定义排序规则
  • sort 方法举例:将数组按里面某个字段从小到大排序
  • 总结

forEach() 介绍

forEach()方法需要一个回调函数(这种函数,是由我们创建但是不由我们调用的)作为参数

回调函数中传递三个参数:

  • 第一个参数,就是当前正在遍历的元素
  • 第二个参数,就是当前正在遍历的元素的索引
  • 第三个参数,就是正在遍历的数组

代码举例:

let myArr = ['王一', '王二', '王三'];

myArr.forEach((item, index, arr) => {
    console.log('item:' + item);
    console.log('index:' + index);
    console.log('arr:' + JSON.stringify(arr));
});

打印结果:

item:王一
index:0
arr:["王一","王二","王三"]
----------
item:王二
index:1
arr:["王一","王二","王三"]
----------
item:王三
index:2
arr:["王一","王二","王三"]
----------

注意:forEach() 没有返回值。也可以理解成:forEach() 的返回值是 undefined

let tempArry = myArr.forEach() 这种方式接收是没有意义的

forEach() 能不能改变原数组?

forEach() 能不能改变原数组?关于这个问题,大部分人会搞错。我们来看看下面的代码

1、数组的元素是基本数据类型:(无法改变原数组)

let numArr = [1, 2, 3];

numArr.forEach((item) => {
    item = item * 2;
});
console.log(numArr); // 打印结果:[1, 2, 3]

上面这段代码,你可要看仔细了,打印结果是 [1, 2, 3],不是 [2, 4, 6]

2、数组的元素是引用数据类型:(直接修改整个元素对象时,无法改变原数组)

let objArr = [
    { name: '云牧', age: 20 },
    { name: '许嵩', age: 30 },
];

objArr.forEach((item) => {
    item = {
        name: '邓紫棋',
        age: '29',
    };
});
console.log(JSON.stringify(objArr));
// 打印结果:[{"name": "云牧","age": 20},{"name": "许嵩","age": 30}]

3、数组的元素是引用数据类型:(修改元素对象里的某个属性时,可以改变原数组)

let objArr = [
    { name: '云牧', age: 28 },
    { name: '许嵩', age: 30 },
];

objArr.forEach((item) => {
    item.name = '邓紫棋';
});
console.log(JSON.stringify(objArr));
// 打印结果:[{"name":"邓紫棋","age":28},{"name":"邓紫棋","age":30}]

所以其实 forEach 不会直接改变调用它的对象,但是那个对象可能会被 callback 函数改变,上述现象如果了解基础数据类型赋值是值传递,而引用数据类型赋值是引用地址的传递后其实就很好理解啦

我B站也已发布关于基础数据和引用数据类型的区别视频,如不清楚此基础,请务必要补齐哦

如果你需要通过 forEach 修改原数组,建议用 forEach 里面的参数 2 和参数 3 来做,具体请看下面的标准做法

forEach() 通过参数 2、参数 3 修改原数组:(标准做法)

// 1、数组的元素是基本数据类型
let numArr = [1, 2, 3];

numArr.forEach((item, index, arr) => {
    arr[index] = arr[index] * 2;
});
console.log(JSON.stringify(numArr)); // 打印结果:[2, 4, 6]

// 2、数组的元素是引用数据类型时,直接修改对象
let objArr = [
    { name: '云牧', age: 28 },
    { name: '许嵩', age: 34 },
];

objArr.forEach((item, index, arr) => {
    arr[index] = {
        name: '小明',
        age: '10',
    };
});
console.log(JSON.stringify(objArr));
// 打印结果:[{"name":"小明","age":"10"},{"name":"小明","age":"10"}]

// 3、数组的元素是引用数据类型时,修改对象的某个属性
let objArr2 = [
    { name: '云牧', age: 28 },
    { name: '许嵩', age: 34 },
];

objArr2.forEach((item, index, arr) => {
    arr[index].name = '小明';
});
console.log(JSON.stringify(objArr2));
// 打印结果:[{"name":"小明","age":28},{"name":"小明","age":34}]

总结

如果纯粹只是遍历数组,那么,可以用 forEach() 方法

但是,如果你想在遍历数组的同时,去改变数组里的元素内容,那么,最好是用 map() 方法来做,map() 方法本身会返回一个经过处理后全新的数组,不要用 forEach() 方法,避免出现一些低级错误

sort() 介绍

sort():对数组的元素进行从小到大来排序(会改变原来的数组)

如果在使用 sort() 方法时不带参,

默认排序顺序是在将元素转换为字符串按照Unicode 编码,从小到大进行排序

举例 1:(当数组中的元素为字符串时)

let arr1 = ['e', 'b', 'd', 'a', 'f', 'c'];

let result = arr1.sort(); // 将数组 arr1 进行排序

console.log('arr1 =' + JSON.stringify(arr1));
console.log('result =' + JSON.stringify(result));

打印结果:

arr1 =["a","b","c","d","e","f"]
result =["a","b","c","d","e","f"]

从上方的打印结果中,我们可以看到,sort 方法会改变原数组,而且方法的返回值也是同样的结果

举例 2:(当数组中的元素为数字时)

let arr2 = [5, 2, 11, 3, 4, 1];

let result = arr2.sort(); // 将数组 arr2 进行排序

console.log('arr2 =' + JSON.stringify(arr2));
console.log('result =' + JSON.stringify(result));

打印结果:

arr2 = [1,11,2,3,4,5]
result = [1,11,2,3,4,5]

上方的打印结果中,你会发现,使用 sort() 排序后,数字11竟然在数字2的前面。这是为啥呢?因为上面讲到了,sort()方法是按照Unicode 编码进行排序的。

那如果我想让 arr2 里的数字,完全按照从小到大排序,怎么操作呢?继续往下看。

sort()方法:带参时,自定义排序规则

如果在 sort()方法中带参,我们就可以自定义排序规则。具体做法如下:

我们可以在 sort()添加一个回调函数,来指定排序规则。

回调函数中需要定义两个形参,浏览器将会分别使用数组中的元素作为实参去调用回调函数。

浏览器根据回调函数的返回值来决定元素的排序:(重要)

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变
  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前

如果只是看上面的文字,可能不太好理解,我们来看看下面的例子,你肯定就能明白

let arr = [5, 2, 11, 3, 4, 1];
arr.sort(function (a, b) {
  console.log("a:" + a, "b:" + b);
});
/*
  a:2 b:5
  a:11 b:2
  a:3 b:11
  a:4 b:3
  a:1 b:4
*/

举例:将数组中的数字按照从小到大排序

写法 1:

let arr = [5, 2, 11, 3, 4, 1];

// 自定义排序规则
let result = arr.sort(function (a, b) {
    if (a > b) {
        // 如果 a 大于 b,则 b 排列 a 之前
        return 1;
    } else if (a < b) {
        // 如果 a 小于 b,,则 a 排列 b 之前
        return -1;
    } else {
        // 如果 a 等于 b,则位置不变
        return 0;
    }
});

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));

打印结果:

arr = [1, 2, 3, 4, 5, 11];
result = [1, 2, 3, 4, 5, 11];

上方代码的写法太啰嗦了,其实也可以简化为如下写法:

写法 2:

let arr = [5, 2, 11, 3, 4, 1];

// 自定义排序规则
let result = arr.sort(function (a, b) {
    return a - b; // 升序排列
    // return b - a; // 降序排列
});

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));

打印结果不变。

上方代码还可以写成 ES6 的形式,也就是将 function 改为箭头函数,其写法如下

写法 3:(箭头函数)

let arr = [5, 2, 11, 3, 4, 1];

// 自定义排序规则
let result = arr.sort((a, b) => {
    return a - b; // 升序排列
});

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));

上方代码,因为函数体内只有一句话,所以可以去掉 return 语句,继续简化为如下写法

写法 4:(推荐)

let arr = [5, 2, 11, 3, 4, 1];

// 自定义排序规则:升序排列
let result = arr.sort((a, b) => a - b);

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));

上面的各种写法中,写法 4 是我们在实战开发中用得最多的。

为了确保代码的简洁优雅,接下来的代码中,凡是涉及到函数,我们将尽量采用 ES6 中的箭头函数来写

sort 方法举例:将数组按里面某个字段从小到大排序

将数组从小到大排序,这个例子很常见。但在实际开发中,总会有一些花样。

下面这段代码,在实际开发中,经常用到,一定要掌握。完整代码如下:

let dataList = [
        {
          title: "品牌鞋子,高品质低价入手",
          publishTime: 200,
        },
        {
          title: "不是很贵,但是很暖",
          publishTime: 100,
        },
        {
          title: "无法拒绝的美食,跟我一起吃吃",
          publishTime: 300,
        },
      ];

 console.log("排序前的数组:" + JSON.stringify(dataList));
 // 将dataList 数组,按照 publishTime 字段,从小到大排序。(会改变原数组)
 dataList.sort((a, b) => parseInt(a.publishTime) - parseInt(b.publishTime));
 console.log("排序后的数组:" + JSON.stringify(dataList));

打印结果:

排序前的数组:[
    {"title":"品牌鞋子,高品质低价入手","publishTime":200},
    {"title":"不是很贵,但是很暖","publishTime":100},
    {"title":"无法拒绝的美食,跟我一起吃吃","publishTime":300}
]

排序后的数组:[
    {"title":"不是很贵,但是很暖","publishTime":100},
    {"title":"品牌鞋子,高品质低价入手","publishTime":200},
    {"title":"无法拒绝的美食,跟我一起吃吃","publishTime":300}
]

上方代码中,有人可能会问: publishTime 字段已经是 nuber 类型了,为啥在排序前还要做一次 parseInt() 转换?

这是因为,这种数据一般是后台接口返回给前端的,数据可能是 number 类型、也可能是 string 类型,所以还是统一先做一次 parseInt() 转换数字比较保险。这是一种良好的工作习惯。

其实上面定义时最好优先使用const,能更多保证程序安全,当需要变量时请采用let。

最后悄悄说句像 forEach、map 、filter、some、every、find、findIndex 这些数组原型上的方法除了可以接受第一个回调函数,同时可以接受第二个值用来指定前面回调函数里 this 值(很少用),但是也要注意如果回调函数如果使用箭头函数则无法绑定 this,因为箭头函数没有 this, 始终是取自上层作用域的 this(面试常考,箭头函数也没有 arguments 不过可以使用剩余参数...解决)。

总结

到此这篇关于Js中forEach修改原数组与sort排序经典场景的文章就介绍到这了,更多相关Js forEach修改原数组内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Javascript数组循环遍历之forEach详解

    1.js 数组循环遍历. 数组循环变量,最先想到的就是 for(var i=0;i<count;i++)这样的方式了. 除此之外,也可以使用较简便的forEach 方式 2.forEach函数. Firefox 和Chrome 的Array 类型都有forEach的函数.使用如下: <!--Add by oscar999--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> &l

  • js sort 二维数组排序的用法小结

    最近在搞js 排序的问题,因为数据库排序太耗资源,如果能转移到客户端去排序,能大大D减少服务器内存消耗.客户端的话,除了js,就是as了,可惜我as学得太烂,所以只能选择js来研究研究了...经过我的测试,js内置方法sort的效率非常高 我们知道在js中默认提供了sort函数,但是这个函数默认是按照数组内容的ascii码升序进行排列的,如果我们要对二维数组排序要如何做呢?在php中是有multi_sort函数可供调用的,但是在js中似乎没有这种函数,但是没关系 ,因为js的sort函数其实也提

  • js中数组(Array)的排序(sort)注意事项说明

    直接看代码吧,测试结果也贴在里面了 复制代码 代码如下: var arrDemo = new Array(); arrDemo[0] = 10; arrDemo[1] = 50; arrDemo[2] = 51; arrDemo[3] = 100; arrDemo.sort(); //调用sort方法后,数组本身会被改变,即影响原数组 alert(arrDemo);//10,100,50,51 默认情况下sort方法是按ascii字母顺序排序的,而非我们认为是按数字大小排序 arrDemo.so

  • js数组forEach实例用法详解

    1.forEach()类似于map(),它还将每个元素依次作用于传入函数,但不会返回新的数组. 2.forEach()常用于遍历数组,用于调用数组的每一个元素,并将其传递给回调函数.传输函数不需要返回值. 实例 var arr=[7,4,6,51,1]; try{arr.forEach((item,index)=>{ if (item<5) { throw new Error("myerr")//创建一个新的error message为myerr } console.log

  • JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍

    •原理: •高级浏览器支持forEach方法 语法:forEach和map都支持2个参数:一个是回调函数(item,index,list)和上下文: •forEach:用来遍历数组中的每一项:这个方法执行是没有返回值的,对原来数组也没有影响: •数组中有几项,那么传递进去的匿名回调函数就需要执行几次: •每一次执行匿名函数的时候,还给其传递了三个参数值:数组中的当前项item,当前项的索引index,原始数组input: •理论上这个方法是没有返回值的,仅仅是遍历数组中的每一项,不对原来数组进行

  • JavaScript Sort 表格排序

    1.你真的懂JavaScript里面的Sort方法吗? 2.你知道JavaScript中 localeCompare 方法的函数体吗? 3.表格排序 方法 要哪些参数? JavaScript中的sort方法直接就提供了排序的功能,不需要我们自己写个循环一个个的判断.但其机制仍然是那样的, 复制代码 代码如下: window.onload=function(){ var MyArr=new Array("red","green","gray");

  • Js数组排序函数sort()介绍

    JavaScript实现多维数组.对象数组排序,其实用的就是原生的sort()方法,用于对数组的元素进行排序. sort() 方法用于对数组的元素进行排序.语法如下: arrayObject.sort(sortby) 返回值为对数组的引用.请注意,数组在原数组上进行排序,不生成副本. 如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序.要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较. 如果想按照其他标准进行排序,

  • JavaScript使用forEach()与jQuery使用each遍历数组时return false 的区别

    原生js使用forEach()与jquery使用each()遍历数组,return false 的区别: 1.使用each()遍历数组a,如下: var a=[20,21,22,23,24]; $.each(a, function(index,val) { console.log('index='+index); if(index==2){ return false; } console.log('val='+val); }); 结果如下: 从运行的效果可以看出,return 相当于循环中的br

  • Js中forEach修改原数组与sort排序经典场景详解

    目录 forEach() 介绍 forEach() 能不能改变原数组? sort() 介绍 如果在使用 sort() 方法时不带参, sort()方法:带参时,自定义排序规则 sort 方法举例:将数组按里面某个字段从小到大排序 总结 forEach() 介绍 forEach()方法需要一个回调函数(这种函数,是由我们创建但是不由我们调用的)作为参数 回调函数中传递三个参数: 第一个参数,就是当前正在遍历的元素 第二个参数,就是当前正在遍历的元素的索引 第三个参数,就是正在遍历的数组 代码举例:

  • [js高手之路]原型式继承与寄生式继承详解

    一.原型式继承本质其实就是个浅拷贝,以一个对象为模板复制出新的对象 function object( o ){ var G = function(){}; G.prototype = o; return new G(); } var obj = { name : 'ghostwu', age : 22, show : function(){ return this.name + ',' + this.age; } }; var obj2 = object( obj ); console.log(

  • JS中原始值和引用值的储存方式示例详解

    在ECMAscript中,变量可以存放两种类型的值,即原始值和引用值 原始值指的是代表原始数据类型的值,也叫基本数据类型,包括:Number.Stirng.Boolean.Null.Underfined 引用值指的是复合数据类型的值,包括:Object.Function.Array.Date.RegExp 根据数据类型不同,有的变量储存在栈中,有的储存在堆中.具体区别如下: 原始变量及他们的值储存在栈中,当把一个原始变量传递给另一个原始变量时,是把一个栈房间的东西复制到另一个栈房间,且这两个原始

  • js中获取URL参数的共用方法getRequest()方法实例详解

    下面通过一段代码给大家介绍js中获取URL参数的共用方法getRequest()方法,具体代码如下所示: getRequest : function() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&am

  • JS中正则表达式只有3种匹配模式(没有单行模式)详解

    JS正则表达式对象模式仅有如下三种:  g (全文查找出现的所有 pattern) i (忽略大小写) m (多行查找) 即没有单行匹配模式,Singleline(单行模式):更改.的含义,使它与每一个字符匹配(包括换行符\n). 如java中 String regex = "(?s)(?<=interface).{0,500}(shutdown)";---------"."表示在一行. 但可以采用[\d\D]或[\w\W]或[\s\S]或(.|\s)*?来解

  • JS中不应该使用箭头函数的四种情况详解

    目录 箭头函数的一些缺点 1.不支持参数对象 2.无法通过apply.call.bind来改变this指针 什么时候不能使用箭头功能 1.请不要在构造函数中使用箭头函数 2.请不要在点击事件中操作this 3.请不要在对象的方法中使用箭头函数. 4.请不要在原型链中使用箭头函数 箭头函数给我们的工作带来了极大的方便,但是它们有什么缺点呢?我们应该一直使用箭头函数吗?我们应该在哪些场景中停止使用箭头函数? 现在,我们开始吧. 箭头函数的一些缺点 1.不支持参数对象 在箭头函数中,我们不能像在普通函

  • Java使用Collections.sort()排序的示例详解

    Java中Collections.sort()排序详解,通过实例代码给大家讲解,具体代码如下所示: public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("beijing"); list.add("shanghai"); list.add("hangzhou"); Collections.

  • C++ sort排序函数用法详解

    目录 用法 两个参数用法 三个参数 string 使用反向迭代器来完成逆序排列 最近在刷ACM经常用到排序,以前老是写冒泡,可把冒泡带到OJ里后发现经常超时,所以本想用快排,可是很多学长推荐用sort函数,因为自己写的快排写不好真的没有sort快,所以毅然决然选择sort函数 用法 1.sort函数可以三个参数也可以两个参数,必须的头文件#include < algorithm>和using namespace std;2.它使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n) 3

  • java中Collections.sort排序函数用法详解

    Comparator是个接口,可重写compare()及equals()这两个方法,用于比价功能:如果是null的话,就是使用元素的默认顺序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f,g这样,当然数字也是这样的. compare(a,b)方法:根据第一个参数小于.等于或大于第二个参数分别返回负整数.零或正整数. equals(obj)方法:仅当指定的对象也是一个 Comparator,并且强行实施与此 Comparator 相同的排序时才返回 true. Collections.

  • Vue.js中的计算属性、监视属性与生命周期详解

    前言 本章节咱们来说一下Vue中两个非常重要的计算属性.监视属性和生命周期,不废话直接上干货 计算属性 计算属性介绍 在模板中可以直接通过插值语法显示一些data中的数据,有些情况下我们需要对数据进行转化或者计算后显示,我们可以使用computed选项来计算,这时有些小伙伴可能就会问,我直接定义函数再调用不就行了,为什么还要整一个计算属性呢?这个问题在下边再做解释,我们先来看一下计算属性怎么用! 入门案例 需求 将人的姓和名拼接在一起 代码 <!DOCTYPE html> <html&g

随机推荐