JavaScript原生Array.sort
方法也能轻松搞定对象数组排序!本文将演示如何使用Array.sort
方法对包含字符串、数字和日期的对象数组进行排序,并提供处理大小写敏感性、数组复制以及常用库的实用技巧。
核心要点
Array.sort
方法可用于排序对象数组,利用比较函数定义字符串、数字、日期和其他属性的排序逻辑。Array.sort
方法会修改其排序的原始数组。为避免这种情况,可以使用Array.slice
方法或扩展运算符创建一个新的数组实例并进行排序。基础数组排序(以及为什么它不起作用)
默认情况下,JavaScript Array.sort
方法会将需要排序的数组中的每个元素转换为字符串,并按Unicode代码点顺序进行比较。
const foo = [9, 1, 4, 'zebroid', 'afterdeck']; foo.sort(); // 返回 [ 1, 4, 9, 'afterdeck', 'zebroid' ] const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }]; bar.sort(); // 返回 [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]
你可能会好奇为什么32在5之前?看似不合理,对吧?其实不然。这是因为数组中的每个元素首先被转换为字符串,而“32”在Unicode顺序中位于“5”之前。
仅使用Array.sort
无法有效地对对象数组进行排序。幸运的是,sort
方法接受一个可选的compareFunction
参数,我们可以用它来排序对象数组。
如何在JavaScript中排序对象数组
要排序对象数组,请使用带有比较函数的sort()
方法。比较函数应用规则,根据我们自定义的逻辑对数组进行排序。它们允许我们根据字符串、整数、日期或任何其他自定义属性对对象数组进行排序。我们稍后将在本文中介绍比较函数的工作原理。
在本演示中,我们将使用一个歌手数组,并按其乐队名称的字母顺序对其进行排序:
const singers = [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, ];
以下比较函数比较每个乐队的(大写)名称:
function compare(a, b) { // 使用 toUpperCase() 忽略字符大小写 const bandA = a.band.toUpperCase(); const bandB = b.band.toUpperCase(); let comparison = 0; if (bandA > bandB) { comparison = 1; } else if (bandA < bandB) { comparison = -1; } return comparison; } singers.sort(compare); /* 返回 [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 } ] */
要反转排序顺序,您可以反转比较函数的返回值:
const foo = [9, 1, 4, 'zebroid', 'afterdeck']; foo.sort(); // 返回 [ 1, 4, 9, 'afterdeck', 'zebroid' ] const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }]; bar.sort(); // 返回 [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]
比较函数返回一个数字,该数字用于通过比较其两个输入(a和b)来确定排序顺序。简单来说,如果整数小于0,则a出现在b之前;如果大于0,则b出现在a之前;如果正好为0,则保持原始顺序。但是你如何确定这个数字取决于你。
让我们来看一个简单的数字数组示例:
const singers = [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, ];
我们可以对其进行一些重构,因为将b减去a也会给我们返回值。此比较函数将数字数组从小到大排序:
function compare(a, b) { // 使用 toUpperCase() 忽略字符大小写 const bandA = a.band.toUpperCase(); const bandB = b.band.toUpperCase(); let comparison = 0; if (bandA > bandB) { comparison = 1; } else if (bandA < bandB) { comparison = -1; } return comparison; } singers.sort(compare); /* 返回 [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 } ] */
它也可以表示为箭头函数,而无需在其他地方定义比较函数:
function compare(a, b) { // ... // 通过乘以 -1 反转返回值 return comparison * -1; }
如果你不熟悉箭头函数,可以在这里阅读更多关于它们的信息:JavaScript中的箭头函数。
如你所见,比较函数可以用多种方式编写,sort()
方法将按指示执行。
让我们完成我们之前的示例,使其更具动态性。让我们创建一个排序函数,你可以使用它来排序对象数组,其值是字符串或数字。此函数有两个参数——我们要排序的键以及结果的顺序(即升序或降序):
const nums = [79, 48, 12, 4]; function compare(a, b) { if (a > b) return 1; if (b > a) return -1; return 0; } nums.sort(compare); // => 4, 12, 48, 79
以下是如何使用它:
function compareNums(a, b) { return a - b; } nums.sort(compareNums)
在上面的代码中,hasOwnProperty
方法用于检查指定的属性是否在每个对象上定义,并且没有通过原型链继承。如果它没有在两个对象上定义,则函数返回0,这会导致排序顺序保持不变(即对象相对于彼此保持不变)。
typeof
运算符还用于检查属性值的类型。这允许函数确定对数组进行排序的正确方法。例如,如果指定属性的值是字符串,则使用toUpperCase
方法将所有字符转换为大写,因此在排序时会忽略字符大小写。
你可以调整上述函数以适应其他数据类型,以及你的脚本可能需要的任何其他需求。
流行的数组排序库
你可能没有时间或耐心在原生JavaScript中创建你自己的排序函数。时间就是金钱,代码需要时间。幸运的是,有各种各样的库可以满足你所有的数组排序需求。以下是一些包含排序函数的辅助库的简短列表……没有特别的顺序;)
快速提示:按日期排序对象数组
要按日期字符串对对象数组进行排序,你只需提供一个比较函数,该函数首先解析日期字符串,然后将它们相互减去:
nums.sort((a, b) => a - b);
快速提示:不修改数组进行排序
与许多其他JavaScript数组函数不同,Array.sort
是会改变(修改)其排序的数组而不是返回新数组的方法之一。为避免这种情况,你可以创建一个要排序的数组的新实例并对其进行修改。这可以使用数组方法或扩展语法来创建数组副本。
const foo = [9, 1, 4, 'zebroid', 'afterdeck']; foo.sort(); // 返回 [ 1, 4, 9, 'afterdeck', 'zebroid' ] const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }]; bar.sort(); // 返回 [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]
使用Array.slice
创建数组副本:
const singers = [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, ];
或者,你可以使用扩展运算符获得相同的效果:
function compare(a, b) { // 使用 toUpperCase() 忽略字符大小写 const bandA = a.band.toUpperCase(); const bandB = b.band.toUpperCase(); let comparison = 0; if (bandA > bandB) { comparison = 1; } else if (bandA < bandB) { comparison = -1; } return comparison; } singers.sort(compare); /* 返回 [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 } ] */
在这两种情况下,输出都是相同的,并且可以在排序任何对象数组之前使用。
function compare(a, b) { // ... // 通过乘以 -1 反转返回值 return comparison * -1; }
快速提示:不区分大小写的方式按字符串排序数组
在我们之前的示例中,我们希望排序对象数组,其值是字符串或数字。但是,如果你知道你只会处理其值为字符串的对象,则可以使用JavaScript的localeCompare
方法来整理代码。
此方法返回一个数字,该数字指示字符串在排序顺序中是位于给定字符串之前、之后还是与之相同。它允许对数组进行不区分大小写的排序:
const nums = [79, 48, 12, 4]; function compare(a, b) { if (a > b) return 1; if (b > a) return -1; return 0; } nums.sort(compare); // => 4, 12, 48, 79
就我们的compareValues
函数而言,这意味着我们可以这样写:
function compareNums(a, b) { return a - b; } nums.sort(compareNums)
你可以在MDN上阅读更多关于localeCompare
的信息。
结论
就是这样——关于使用原生JavaScript排序对象数组的简短介绍。尽管许多库提供了这种动态排序功能,但正如所示,自己实现此功能并不难。此外,了解幕后发生的事情也很有益。
为了构建对原生JavaScript基础的更全面的理解,我们推荐JavaScript:从新手到忍者。从头开始学习JavaScript,包括ES6,并通过一系列项目来实践你的新知识。
关于如何在JavaScript中排序对象数组的常见问题解答
是的。JavaScript提供了内置方法来帮助排序数组元素。
你可以使用Array.prototype.sort()
方法并提供自定义比较函数来对JavaScript中的对象数组进行排序。比较函数应该比较每个对象的相关属性。
你可以通过向比较函数提供键来动态地根据不同的键对对象数组进行排序。这允许你按各种属性进行排序。要按JavaScript中特定键(属性)对对象数组进行排序,你可以使用Array.prototype.sort()
方法以及自定义比较函数,该函数比较每个对象的所需键的值。
要根据运行时确定的键(属性)动态地对JavaScript中的对象数组进行排序,你可以创建一个函数,该函数接受数组和键作为参数。然后,此函数可以使用Array.prototype.sort()
方法以及自定义比较函数来访问用于排序的动态提供的键。
是否有任何库可以简化对象数组的排序?是的,像Lodash和Underscore.js这样的库提供了用于排序对象数组的实用程序函数,并具有附加功能和便利性。但是,JavaScript的内置sort()
方法通常足以满足基本的排序需求。
按对象键排序是否区分大小写?是的,默认情况下,按对象键排序区分大小写。你可以使用localeCompare()
方法执行不区分大小写的排序。
以上是用sort()方法在JavaScript中对对象进行排序的详细内容。更多信息请关注PHP中文网其他相关文章!