JS对象数组的排序(二十二)

白发戴花君莫笑,岁月从不败美人。 愿,像你我一如既往地好看。

上一章简单介绍了JS的数组和对象深层拷贝(二十一),如果没有看过,请观看上一章

本文参考 ‘那时候的我’ 前辈的文章: https://www.cnblogs.com/xljzlw/p/3694861.html

一. JS 数组排序

在JS中,有一个排序方法, sort(), 可以直接 arr.sort(), 进行相应的排序。但这个排序,只是针对的单值,如字符串,数值类型的排序,无法针对JS对象数组进行排序。 需要在sort() 方法中添加相应的排序规则的方法。 接下来,讲解一下 Array 中的sort() 方法。
按照ASCII 的顺序进行排序。

ASCII 码图片:
图片来源于百度百科

图片来源于百度百科: https://baike.baidu.com/item/ASCII/309296

二. JS 针对字符串的排序。 (按照ASCII 进行排序)

数组中存放的是单值 字符串形式的。

function validateArrF1(){
	//1.定义字符串的数组。
	var arr=['A','B','a','b','ACD','ACE'];
	//2. 将数组进行排序。 单值的。
	arr.sort();
	//3.输出新的排序后的数组。
	console.log(arr.toString());
}

运行这个方法,结果为:

有图片。

A的值为65,小a 为97, 按照ASCII 进行排序。

三. JS针对数字的排序

三.一 默认toString() 转换成字符串再排序

数组中存放的是单值 数字形式。

function validateArrF2(){
	//1.定义数字形式的数组。
	var arr=[123,125001,234,234001,100,100001,101101];  //会先将其转换成字符串。
	//2. 将数组进行排序。 单值的。
	arr.sort();
	//3.输出新的排序后的数组。
	console.log(arr.toString());
}

运行,

有图片。

发现,并没有按照 数字大小的顺序进行排序。 内部是先将数字转换成了字符串 toString(), 然后成为了数字型字符串,按照ASCII 码进行排序。

这样,很明显是不可以的。需要自定义比较器。 (但有时,也会按照这种形式排序,如: 科目的编号, 101为父,101101, 101102, 102,102101,102102 等, 这样排序可以看出父与子之间的关系。 但那时,科目编号本身类型就是字符串)

三.二 自定义比较器,令其按照数字大小进行排序

//定义数字比较的方法。
function compareNum(x,y){
	if(x<y){  //是升序排序。
		return -1;
	}else if(x>y){
		return 1;
	}else{
		return 0;
	}
}
function validateArrF4(){
	//1.定义数字形式的数组。
	var arr=[123,125001,234,234001,100,100001,101101];  //会先将其转换成字符串。
	//2. 将数组进行排序。 sort() 方法里面传入比较的函数,内包。
	arr.sort(compareNum);
	//3.输出新的排序后的数组。
	console.log(arr.toString());
}

在sort() 方法里面放入比较的函数。
展示输出:

在这里插入图片描述

四。JS针对数字与字符串混合的排序。

JS数组中,可能既存在数字,也存在字符串,那么这个时候,如何进行排序呢?

function validateArrF3(){
	//1.定义数字形式的数组。
	var arr1=['A','B','a','b','ACD','ACE'];
	var arr2=[123,125001,234,234001,100,100001,101101];  //会按照ASCII 码进行相应的排序。
	var arr=arr1.concat(arr2);
	//2. 将数组进行排序。 单值的。
	arr.sort();
	//3.输出新的排序后的数组。
	console.log(arr.toString());
}

展示输出:
在这里插入图片描述

数字会先转换成字符串,然后按照字符串进行相应的排序。 其中,数字0~9 为 48~57, 是在A 65, a97 之前的,所以会先输出数字,再输出字符串。

如果这个时候,在arr.sort() 里面放入 数字排序的方法呢?

arr.sort(compareNum);

显示效果如下:

在这里插入图片描述

这个时候,很奇怪,为什么是这样的呢?

其实,A 字符是可以转换成 数字的, 是65, a是字符,也可以转换,转换成 97. 变成了数字。 字符串只取其中的第一个字符进行比较,如果相同,才比较第二个。

五. 对象数组的排序

要进行排序的六个对象。 以user 对象为例。

//1.定义要排序的对象。
	var user1={"code":"101","name":"两个蝴蝶飞","age":24,"sex":"男","description":"一个快乐的程序员101"};
	var user2={"code":"102","name":"精灵妹","age":24,"sex":"女","description":"一个快乐的精灵102"};
	var user3={"code":"103","name":"老蝴蝶","age":25,"sex":"男","description":"一个快乐的程序员103"};
	var user4={"code":"104","name":"蝴蝶飞","age":25,"sex":"男","description":"一个快乐的程序员104"};
	var user5={"code":"105","name":"精小妹","age":24,"sex":"女","description":"一个快乐的精灵105"};
	var user6={"code":"106","name":"蝴蝶飞3号","age":24,"sex":"男","description":"一个快乐的程序员106"};

五.一 单纯的对象 sort() 方法

function validateArrF5(){
	//1.定义要排序的对象。
	var user1={"code":"101","name":"两个蝴蝶飞","age":24,"sex":"男","description":"一个快乐的程序员101"};
	var user2={"code":"102","name":"精灵妹","age":24,"sex":"女","description":"一个快乐的精灵102"};
	var user3={"code":"103","name":"老蝴蝶","age":25,"sex":"男","description":"一个快乐的程序员103"};
	var user4={"code":"104","name":"蝴蝶飞","age":25,"sex":"男","description":"一个快乐的程序员104"};
	var user5={"code":"105","name":"精小妹","age":24,"sex":"女","description":"一个快乐的精灵105"};
	var user6={"code":"106","name":"蝴蝶飞3号","age":24,"sex":"男","description":"一个快乐的程序员106"};
	//2. 将对象放置在数组里面。
	var arr=new Array();
	//故意,将2与1调换位置。
	arr.push(user2);
	arr.push(user1);
	arr.push(user3);
	arr.push(user4);
	arr.push(user5);
	arr.push(user6);
	//3. 将数组进行排序。
	arr.sort();  //发现,并没有排序。 是按照数组放置的顺序进行的
	//3.输出新的排序后的数组。
	for(var i=0;i<arr.length;i++){
		console.log((i+1)+":"+JSON.stringify(arr[i]));
	}
}

展示效果:

有图片。

老蝴蝶发现,并没有排序。 是按照数组放置的顺序进行的。

五.二 比较方法里面写死属性

如果想按照 编号进行排序,那么需要自定义排序方法了。

var compareObject=function(obj1,obj2){
	//内定的,按照排序进行排序。 对象的编号 code 写死在这里面。
	var code1=obj1["code"];
	var code2=obj2["code"];
	//console.log("输出值:"+code1+","+code2);
	//编号,如果是字符串的话,则要先将其转换成字符串。
	//code1=code1.toString();
	//code2=code2.toString();
	if(code1<code2){
		return -1;
	}else if(code1>code2){
		return 1;
	}else{
		return 0;
	}
	// 也可以直接写,  return code1-code2;
}
function validateArrF6(){
	//1.定义要排序的对象。  可以在前面加A变成字符串。
	var user1={"code":"101","name":"两个蝴蝶飞","age":24,"sex":"男","description":"一个快乐的程序员101"};
	var user2={"code":"102","name":"精灵妹","age":24,"sex":"女","description":"一个快乐的精灵102"};
	var user3={"code":"103","name":"老蝴蝶","age":25,"sex":"男","description":"一个快乐的程序员103"};
	var user4={"code":"104","name":"蝴蝶飞","age":25,"sex":"男","description":"一个快乐的程序员104"};
	var user5={"code":"105","name":"精小妹","age":24,"sex":"女","description":"一个快乐的精灵105"};
	var user6={"code":"106","name":"蝴蝶飞3号","age":24,"sex":"男","description":"一个快乐的程序员106"};
	//2. 将对象放置在数组里面。
	var arr=new Array();
	//故意,将2与1调换位置。
	arr.push(user2);
	arr.push(user1);
	arr.push(user3);
	arr.push(user4);
	arr.push(user5);
	arr.push(user6);
	//3. 将数组进行排序。
	arr.sort(compareObject);
	//3.输出新的排序后的数组。
	for(var i=0;i<arr.length;i++){
		console.log((i+1)+":"+JSON.stringify(arr[i]));
	}
}

展示:

有图片。

其中,obj1 为前一个对象,obj2 为后一个对象。

老蝴蝶把 对象user 的编号 code 硬编码在方法里面, 那么这个方法 compareObject() 便只能按照编号进行排序。 如果想按照年龄进行排序,则需要再重新写一个方法,这样扩展性不好。

五.三 比较的属性由外部传入

如按照年龄进行相应的排序。

var compareObjectByProp=function(prop){
	return function compareObject(obj1,obj2){
		var code1=obj1[prop];
		var code2=obj2[prop];
		//根据属性值的类型,可能需要进行一下相应的判断。
		//如果数字的话,就转换成数字,进行数字之间的比较。 如果是数字的话,要两个都是数字,不然没有意义。 一个数字,另外一个是字符串,那么数字只是数字型的字符串,类型并不是数字。
		if (!isNaN(Number(code1)) && !isNaN(Number(code2))) {
			code1=Number(code1);
			code2=Number(code2);
		}
		return code1-code2;  //代替以前的 if elseif else 的判断。
	}
}

function validateArrF7(){
	//1.定义要排序的对象。  可以在前面加A变成字符串。
	var user1={"code":"101","name":"两个蝴蝶飞","age":24,"sex":"男","description":"一个快乐的程序员101"};
	var user2={"code":"102","name":"精灵妹","age":24,"sex":"女","description":"一个快乐的精灵102"};
	var user3={"code":"103","name":"老蝴蝶","age":25,"sex":"男","description":"一个快乐的程序员103"};
	var user4={"code":"104","name":"蝴蝶飞","age":25,"sex":"男","description":"一个快乐的程序员104"};
	var user5={"code":"105","name":"精小妹","age":24,"sex":"女","description":"一个快乐的精灵105"};
	var user6={"code":"106","name":"蝴蝶飞3号","age":24,"sex":"男","description":"一个快乐的程序员106"};
	//2. 将对象放置在数组里面。
	var arr=new Array();
	//故意,将2与1调换位置。
	arr.push(user2);
	arr.push(user1);
	arr.push(user3);
	arr.push(user4);
	arr.push(user5);
	arr.push(user6);
	//3. 将数组进行排序。 将属性 年龄 age传入进去。
	arr.sort(compareObjectByProp("age"));
	//3.输出新的排序后的数组。
	for(var i=0;i<arr.length;i++){
		console.log((i+1)+":"+JSON.stringify(arr[i]));
	}
}

展示效果:

有图片。

这样,就可以按照年龄进行相应的排序了。

五.四 传入属性并且传入排序的方式,是升序,还是降序。

如传入年龄,但是是降序排序。

var compareObjectByProp=function(prop,order){
	return function compareObject(obj1,obj2){
		var code1=obj1[prop];
		var code2=obj2[prop];
		//根据属性值的类型,可能需要进行一下相应的判断。
		//如果数字的话,就转换成数字,进行数字之间的比较。 如果是数字的话,要两个都是数字。 一个数字,另外一个是字符串,那么数字只是数字型的字符串,类型并不是数字。
		if (!isNaN(Number(code1)) && !isNaN(Number(code2))) {
			code1=Number(code1);
			code2=Number(code2);
		}
		if(order&&order.toLowerCase()=="desc"){ //有值,并且值为desc
			return code2-code1;
		}
		return code1-code2;  //代替以前的 if elseif else 的判断。
	}
}
function validateArrF8(){
	//1.定义要排序的对象。  可以在前面加A变成字符串。
	var user1={"code":"101","name":"两个蝴蝶飞","age":24,"sex":"男","description":"一个快乐的程序员101"};
	var user2={"code":"102","name":"精灵妹","age":24,"sex":"女","description":"一个快乐的精灵102"};
	var user3={"code":"103","name":"老蝴蝶","age":25,"sex":"男","description":"一个快乐的程序员103"};
	var user4={"code":"104","name":"蝴蝶飞","age":25,"sex":"男","description":"一个快乐的程序员104"};
	var user5={"code":"105","name":"精小妹","age":24,"sex":"女","description":"一个快乐的精灵105"};
	var user6={"code":"106","name":"蝴蝶飞3号","age":24,"sex":"男","description":"一个快乐的程序员106"};
	//2. 将对象放置在数组里面。
	var arr=new Array();
	//故意,将2与1调换位置。
	arr.push(user2);
	arr.push(user1);
	arr.push(user3);
	arr.push(user4);
	arr.push(user5);
	arr.push(user6);
	//3. 将数组进行排序。
	arr.sort(compareObjectByProp("age","desc"));
	//3.输出新的排序后的数组。
	for(var i=0;i<arr.length;i++){
		console.log((i+1)+":"+JSON.stringify(arr[i]));
	}
}

展示效果:

在这里插入图片描述

如果传入的order 没有值,那么就默认是 asc, 升序。 如果传入的是asc,那么就是升序。 只有当传入desc 时才是降序。 当然,老蝴蝶这只是一个简单的排序。

五.五 多属性排序

想先按照年龄从小到大排序,如果年龄一致,则按照编号从大到小排序。
这个时候,可不能简单的先按照年龄从小到大排序,然后再编号从大到小排序。

arr=arr.sort(compareObjectByProp("age","asc"));
arr=arr.sort(compareObjectByProp("code","desc"));

这个时候,会以最后的一个排序为准,即以编号从大到小为准。

有图片。

这个时候,就需要重新写方法了, 写两个属性的方法。

var compareObjectByProp=function(prop1,prop2){
	return function compareObject(obj1,obj2){
		//取出第一列的值。
		var code1=obj1[prop1];
		var code2=obj2[prop1];
		//根据属性值的类型,可能需要进行一下相应的判断。
		//如果数字的话,就转换成数字,进行数字之间的比较。 如果是数字的话,要两个都是数字。 一个数字,另外一个是字符串,那么数字只是数字型的字符串,类型并不是数字。
		if (!isNaN(Number(code1)) && !isNaN(Number(code2))) {
			code1=Number(code1);
			code2=Number(code2);
		}
		//取出第二列的值。
		var code3=obj1[prop2];
		var code4=obj2[prop2];
		//根据属性值的类型,可能需要进行一下相应的判断。
		//如果数字的话,就转换成数字,进行数字之间的比较。 如果是数字的话,要两个都是数字。 一个数字,另外一个是字符串,那么数字只是数字型的字符串,类型并不是数字。
		if (!isNaN(Number(code3)) && !isNaN(Number(code4))) {
			code3=Number(code3);
			code4=Number(code4);
		}
		if(code1<code2){   //升序和降序 写在方法里面,当然,也可以通过参数传入进来。
			return -1;
		}else if(code1>code2){
			return 1;
		}else {
			//return code3-code4;
			return code4-code3;
		}
		
	}
}

function validateArrF9(){
	//1.定义要排序的对象。  可以在前面加A变成字符串。
	var user1={"code":"101","name":"两个蝴蝶飞","age":24,"sex":"男","description":"一个快乐的程序员101"};
	var user2={"code":"102","name":"精灵妹","age":24,"sex":"女","description":"一个快乐的精灵102"};
	var user3={"code":"103","name":"老蝴蝶","age":25,"sex":"男","description":"一个快乐的程序员103"};
	var user4={"code":"104","name":"蝴蝶飞","age":25,"sex":"男","description":"一个快乐的程序员104"};
	var user5={"code":"105","name":"精小妹","age":24,"sex":"女","description":"一个快乐的精灵105"};
	var user6={"code":"106","name":"蝴蝶飞3号","age":24,"sex":"男","description":"一个快乐的程序员106"};
	//2. 将对象放置在数组里面。
	var arr=new Array();
	//故意,将2与1调换位置。
	arr.push(user2);
	arr.push(user1);
	arr.push(user3);
	arr.push(user4);
	arr.push(user5);
	arr.push(user6);
	//3. 将数组进行排序。  可以进行单个函数的多次调用。
	arr=arr.sort(compareObjectByProp("age","code"));
	//3.输出新的排序后的数组。
	for(var i=0;i<arr.length;i++){
		console.log((i+1)+":"+JSON.stringify(arr[i]));
	}
}

展示:

有图片。

当然,升序和降序也可以当成参数传入进去, 也可以多个值,如 年龄,成绩,编号 等排序, 但这种情况不常用,一般两个属性就够了,而且是固定好排序的。

这就是对象数组排序的基本方式。

谢谢!!!

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页