令数组中的对象根据数字大小进行排序

简介: 令数组中的对象根据数字大小进行排序

JavaScript sort() 方法

JavaScript Array 对象

定义和用法

sort() 方法用于对数组的元素进行排序。

语法

arrayObject.sort(sortby)
参数 描述
sortby 可选。规定排序顺序。必须是函数。

返回值

对数组的引用。请注意,数组在原数组上进行排序,不生成副本。

说明

如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。

如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:

  • 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
  • 若 a 等于 b,则返回 0。
  • 若 a 大于 b,则返回一个大于 0 的值。

一、普通数组排序  

  js中用方法sort()为数组排序。sort()方法有一个可选参数,是用来确定元素顺序的函数。如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序。如:

var arr = ["a", "b", "A", "B"];
arr.sort();
console.log(arr);//>["A", "B", "a", "b"]

因为字母A、B的ASCII值分别为65、66,而a、b的值分别为97、98,所以上面输出的结果是 ["A", "B", "a", "b"] 。

如果数组元素是数字呢,结果会是怎样?

var arr = [15, 8, 25, 3];
arr.sort();
console.log(arr);//>[15, 25, 3, 8]

结果是 [15, 25, 3, 8] 。其实,sort方法会调用每个数组项的toString()方法,得到字符串,然后再对得到的字符串进行排序。虽然数值15比3大,但在进行字符串比较时"15"则排在"3"前面。显然,这种结果不是我们想要的,这时,sort()方法的参数就起到了作用,我们把这个参数叫做比较函数。

  比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回0,如果第一个参数应该位于第二个之后则返回一个正数。例子:

var arr = [23, 9, 4, 78, 3];
var compare = function (x, y) {//比较函数
    if (x < y) {
        return -1;
    } else if (x > y) {
        return 1;
    } else {
        return 0;
    }
}
console.log(arr.sort(compare));//> [3, 4, 9, 23, 78] 

结果为 [3, 4, 9, 23, 78] ,返回了我们想要的结果。如果要按降序排序,比较函数写成这样即可:

var compare = function (x, y) {
    if (x < y) {
        return 1;
    } else if (x > y) {
        return -1;
    } else {
        return 0;
    }
}

我们并不能用比较函数比较一个不能转化为数字的字符串与数字的顺序:

var arr = ["b", 5];
console.log(arr.sort(compare))

结果是 ["b", 5] 。因为比较函数在比较时,会把先把字符串转化为数字,然后再比较,字符串b不能转化为数字,所以就不能比较大小。然而,当不用比较函数时,会比较ASCII值,所以结果是 [5, "b"] 。

二、数组对象排序

如果数组项是对象,我们需要根据数组项的某个属性对数组进行排序,要怎么办呢?其实和前面的比较函数也差不多:

var arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}];
var compare = function (obj1, obj2) {
    var val1 = obj1.name;
    var val2 = obj2.name;
    if (val1 < val2) {
        return -1;
    } else if (val1 > val2) {
        return 1;
    } else {
        return 0;
    }            
} 
console.log(arr.sort(compare));

  输出结果为 [Object { name="wlz", age=25}, Object { name="zlw", age=24}] ,可以看到数组已经按照 name 属性进行了排序。我们可以对上面的比较函数再改造一下:

var compare = function (prop) {
    return function (obj1, obj2) {
        var val1 = obj1[prop];
        var val2 = obj2[prop];
        if (val1 < val2) {
            return -1;
        } else if (val1 > val2) {
            return 1;
        } else {
            return 0;
        }            
    } 
}

如果想按照 age 进行排序, arr.sort(compare("age")) 即可。

  但是对age属性进行排序时需要注意了,如果age属性的值是数字,那么排序结果会是我们想要的。但很多时候我们从服务器传回来的数据中,属性值通常是字符串。现在我把上面的数组改为:

var arr = [{name: "zlw", age: "24"}, {name: "wlz", age: "5"}];

可以看到,我把 age 属性由数字改为了字符串,第二个数组项的 age 值改为了 "5" 。再次调用 arr.sort(compare("age")) 后,结果为:

[Object { name="zlw", age="24"}, Object { name="wlz", age="5"}]

我们的期望是5排在25前面,但是结果不是。这是因为当两个数字字符串比较大小时,会比较它们的ASCII值大小,比较规则是:从第一个字符开始,顺次向后直到出现不同的字符为止,然后以第一个不同的字符的ASCII值确定大小。所以"24"与"5"比较大小时,先比较”2“与"5"的ASCII值,显然”2“的ASCII值比"5"小,即确定排序顺序。

现在,我们需要对比较函数再做一些修改:

var compare = function (prop) {
    return function (obj1, obj2) {
        var val1 = obj1[prop];
        var val2 = obj2[prop];
        if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
            val1 = Number(val1);
            val2 = Number(val2);
        }
        if (val1 < val2) {
            return -1;
        } else if (val1 > val2) {
            return 1;
        } else {
            return 0;
        }            
    } 
}

在比较函数中,先把比较属性值转化为数字 Number(val1) 再通过 !isNaN(Number(val1)) 判断转化后的值是不是数字(有可能是NaN),转化后的值如果是数字,则比较转换后的值,这样就可以得到我们想要的结果了, 调用 arr.sort(compare("age")) 得到:

[Object { name="wlz", age="5"}, Object { name="zlw", age="24"}]

可以看到,确实是按正确的方式排序了。

对数组中的项先分类在排序

方案一

const leibieData = [
  {
    leibie: "涉恐",
    zongrenshu: 32
  },
  {
    leibie: "涉稳",
    zongrenshu: 28
  },
  {
    leibie: "部前科",
    zongrenshu: 44
  },
  {
    leibie: "涉毒",
    zongrenshu: 29
  },
  {
    leibie: "在逃",
    zongrenshu: 22
  },
  {
    leibie: "涉恐",
    zongrenshu: 45
  },
  {
    leibie: "涉毒",
    zongrenshu: 19
  },
  {
    leibie: "部前科",
    zongrenshu: 11
  },
  {
    leibie: "精神病人",
    zongrenshu: 11
  },
  {
    leibie: "上访",
    zongrenshu: 122
  }
];
var compare = function(prop) {
  return function(obj1, obj2) {
    var val1 = obj1[prop];
    var val2 = obj2[prop];
    if (val1 < val2) {
      return 1;
    } else if (val1 > val2) {
      return -1;
    } else {
      return 0;
    }
  };
};
leibieData.sort(compare("zongrenshu"));
console.log(leibieData);
const sorts = ["涉恐", "涉稳", "涉毒", "部前科", "在逃", "上访", "精神病人"];
let newLeibieData = [];
for (let i = 0; i < sorts.length; i++) {
  let sort = sorts[i];
  function hasSameName(element, index, array) {
    if (element.leibie === sort) {
      console.log(element.leibie);
      console.log(index);
    }
    return element.leibie === sort;
  }
  let middle = leibieData.filter(hasSameName);
  console.log(middle);
  newLeibieData = newLeibieData.concat(middle);
}
console.log(newLeibieData);

方案二

const jingzhongData = [
  {
    leibie: "涉恐",
    zongrenshu: 32
  },
  {
    leibie: "涉稳",
    zongrenshu: 28
  },
  {
    leibie: "部前科",
    zongrenshu: 44
  },
  {
    leibie: "涉毒",
    zongrenshu: 29
  },
  {
    leibie: "在逃",
    zongrenshu: 22
  },
  {
    leibie: "涉恐",
    zongrenshu: 45
  },
  {
    leibie: "涉毒",
    zongrenshu: 19
  },
  {
    leibie: "部前科",
    zongrenshu: 11
  },
  {
    leibie: "精神病人",
    zongrenshu: 11
  },
  {
    leibie: "上访",
    zongrenshu: 122
  }
];

const sort3 = jingzhongData.sort((a, b) => {
  if (a.leibie > b.leibie) {
    return 1;
  } else if (a.leibie < b.leibie) {
    return -1;
  } else {
    return b.zongrenshu - a.zongrenshu;
  }
});

console.log(sort3);
相关文章
|
7月前
|
机器学习/深度学习 算法 测试技术
DeepSeek-R1-0528:小更新大升级
今天,DeepSeek R1 开源发布了其“小版本”升级——DeepSeek-R1-0528。
754 24
|
6月前
|
新能源 API 开发者
车辆限行查询API的实战指南:让限行管理从此 “有码可循”
随着全国机动车保有量突破4.53亿辆,交通拥堵与污染问题日益严峻,各城市陆续实施限行政策。探数API推出的车辆限行查询服务覆盖200+城市,提供实时限行数据,包括本地/外地燃油车及新能源车的限行规则、区域和时间等信息。其功能涵盖单个城市限行政策查询与支持城市的全面列表,助力用户精准规划出行。通过HTTP POST请求即可轻松接入,适用于导航平台和个人开发者。在“双碳”目标下,该API推动绿色出行与智能交通发展,为个人、企业和城市治理提供高效解决方案。
501 5
|
人工智能 IDE Devops
当「软件研发」遇上 AI 大模型
大模型和软件工具链的结合,使软件研发进入下一个时代。那它第一个落脚点在哪?实际上就是辅助编程,所以我们就开始打造了通义灵码这款产品,它是一个基于代码大模型的的 AI 辅助工具。本文会分为三个部分来分享。第一部分先介绍 AIGC 对软件研发的根本性影响,从宏观上介绍当下的趋势;第二部分将介绍 Copilot 模式,第三部分是未来软件研发 Agent 产品的进展。
523 88
|
API
天气预报-腾讯天气-7天-IP查询版免费API接口教程
根据IP地址自动查询该IP归属地7天天气预报的腾讯天气API。请求地址为`https://cn.apihz.cn/api/tianqi/tengxunip.php`,支持GET和POST请求。需提供ID、Key和IP地址作为参数。返回数据包含天气预报信息。
488 3
Echarts——如何默认选中图表并显示tooltip
Echarts——如何默认选中图表并显示tooltip
694 1
|
缓存 Web App开发 自然语言处理
关于解决chatGPT注册不了报错:chatGPT邮箱不支持
ChatGPT 开放了免费注册功能。然而,在用户创建过程中,一些人遇到了如下所示的提示信息:“Oops! The email you provided is not supported”,中文翻译为“糟糕,邮箱不支持”。
1123 4
|
API UED
深入理解 uni-app 中的加载提示:uni.showLoading
深入理解 uni-app 中的加载提示:uni.showLoading
7379 0
|
定位技术
29-Vue之ECharts-散点图
29-Vue之ECharts-散点图
|
JavaScript 前端开发
vue2.0 + element-ui +iframe在页面 中嵌入外部网站
vue2.0 + element-ui +iframe在页面 中嵌入外部网站
590 1
vue3中的父子间传值
vue3中的父子间传值
170 1