按字符串属性值对对象数组进行排序

我有一个JavaScript对象数组:

var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];

如何在JavaScript中按last_nom的值对它们进行排序?

我知道sort(a,b),但这似乎只适用于字符串和数字。我需要向我的对象添加toString()方法吗?

2804145 次浏览

编写自己的比较函数很容易:

function compare( a, b ) {if ( a.last_nom < b.last_nom ){return -1;}if ( a.last_nom > b.last_nom ){return 1;}return 0;}
objs.sort( compare );

或内联(c/o Marco Demaio):

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0))

或简化为数字(c/o安德烈·菲格雷多):

objs.sort((a,b) => a.last_nom - b.last_nom); // b - a for reverse sort

如果你有重复的姓氏,你可以按名字排序——

obj.sort(function(a,b){if(a.last_nom< b.last_nom) return -1;if(a.last_nom >b.last_nom) return 1;if(a.first_nom< b.first_nom) return -1;if(a.first_nom >b.first_nom) return 1;return 0;});

除了使用自定义比较函数,您还可以使用自定义toString()方法(由默认比较函数调用)创建对象类型:

function Person(firstName, lastName) {this.firtName = firstName;this.lastName = lastName;}
Person.prototype.toString = function() {return this.lastName + ', ' + this.firstName;}
var persons = [ new Person('Lazslo', 'Jamf'), ...]persons.sort();

您还可以创建一个动态排序函数,根据您传递的值对对象进行排序:

function dynamicSort(property) {var sortOrder = 1;if(property[0] === "-") {sortOrder = -1;property = property.substr(1);}return function (a,b) {/* next line works with strings and numbers,* and you may want to customize it to your needs*/var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;return result * sortOrder;}}

所以你可以有一个像这样的对象数组:

var People = [{Name: "Name", Surname: "Surname"},{Name:"AAA", Surname:"ZZZ"},{Name: "Name", Surname: "AAA"}];

…当你这样做时,它会起作用:

People.sort(dynamicSort("Name"));People.sort(dynamicSort("Surname"));People.sort(dynamicSort("-Surname"));

其实这已经回答了问题。下面的部分是因为很多人联系我,抱怨它不适用于多个参数

多个参数

您可以使用下面的函数生成具有多个排序参数的排序函数。

function dynamicSortMultiple() {/** save the arguments object as it will be overwritten* note that arguments object is an array-like object* consisting of the names of the properties to sort by*/var props = arguments;return function (obj1, obj2) {var i = 0, result = 0, numberOfProperties = props.length;/* try getting a different result from 0 (equal)* as long as we have extra properties to compare*/while(result === 0 && i < numberOfProperties) {result = dynamicSort(props[i])(obj1, obj2);i++;}return result;}}

这将使你能够做这样的事情:

People.sort(dynamicSortMultiple("Name", "-Surname"));

数组子类化

对于我们中可以使用ES6的幸运儿,它允许扩展本机对象:

class MyArray extends Array {sortBy(...args) {return this.sort(dynamicSortMultiple(...args));}}

这将使:

MyArray.from(People).sortBy("Name", "-Surname");

underscore.js

使用下划线,它的小而真棒…

sortBy_. sortBy(list, iterator,[text])返回list,按运行每个值的结果升序排列通过迭代器。迭代器也可以是属性的字符串名称按(例如长度)排序。

var objs = [{ first_nom: 'Lazslo',last_nom: 'Jamf' },{ first_nom: 'Pig', last_nom: 'Bodine'  },{ first_nom: 'Pirate', last_nom: 'Prentice' }];
var sortedObjs = _.sortBy( objs, 'first_nom' );

使用原型继承简单快速地解决此问题:

Array.prototype.sortBy = function(p) {return this.slice(0).sort(function(a,b) {return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;});}

示例/用法

objs = [{age:44,name:'vinay'},{age:24,name:'deepak'},{age:74,name:'suresh'}];
objs.sortBy('age');// Returns// [{"age":24,"name":"deepak"},{"age":44,"name":"vinay"},{"age":74,"name":"suresh"}]
objs.sortBy('name');// Returns// [{"age":24,"name":"deepak"},{"age":74,"name":"suresh"},{"age":44,"name":"vinay"}]

更新时间:不再修改原始数组。

埃格·奥兹坎代码的附加desc参数

function dynamicSort(property, desc) {if (desc) {return function (a, b) {return (a[property] > b[property]) ? -1 : (a[property] < b[property]) ? 1 : 0;}}return function (a, b) {return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;}}

将Ege的动态解决方案与Vinay的想法相结合,您将获得一个很好的健壮解决方案:

Array.prototype.sortBy = function() {function _sortByAttr(attr) {var sortOrder = 1;if (attr[0] == "-") {sortOrder = -1;attr = attr.substr(1);}return function(a, b) {var result = (a[attr] < b[attr]) ? -1 : (a[attr] > b[attr]) ? 1 : 0;return result * sortOrder;}}
function _getSortFunc() {if (arguments.length == 0) {throw "Zero length arguments not allowed for Array.sortBy()";}var args = arguments;return function(a, b) {for (var result = 0, i = 0; result == 0 && i < args.length; i++) {result = _sortByAttr(args[i])(a, b);}return result;}}return this.sort(_getSortFunc.apply(null, arguments));}
Usage:
// Utility for printing objectsArray.prototype.print = function(title) {console.log("************************************************************************");console.log("**** " + title);console.log("************************************************************************");for (var i = 0; i < this.length; i++) {console.log("Name: " + this[i].FirstName, this[i].LastName, "Age: " + this[i].Age);}}
// Setup sample datavar arrObj = [{FirstName: "Zach",LastName: "Emergency",Age: 35},{FirstName: "Nancy",LastName: "Nurse",Age: 27},{FirstName: "Ethel",LastName: "Emergency",Age: 42},{FirstName: "Nina",LastName: "Nurse",Age: 48},{FirstName: "Anthony",LastName: "Emergency",Age: 44},{FirstName: "Nina",LastName: "Nurse",Age: 32},{FirstName: "Ed",LastName: "Emergency",Age: 28},{FirstName: "Peter",LastName: "Physician",Age: 58},{FirstName: "Al",LastName: "Emergency",Age: 51},{FirstName: "Ruth",LastName: "Registration",Age: 62},{FirstName: "Ed",LastName: "Emergency",Age: 38},{FirstName: "Tammy",LastName: "Triage",Age: 29},{FirstName: "Alan",LastName: "Emergency",Age: 60},{FirstName: "Nina",LastName: "Nurse",Age: 54}];
//Unit TestsarrObj.sortBy("LastName").print("LastName Ascending");arrObj.sortBy("-LastName").print("LastName Descending");arrObj.sortBy("LastName", "FirstName", "-Age").print("LastName Ascending, FirstName Ascending, Age Descending");arrObj.sortBy("-FirstName", "Age").print("FirstName Descending, Age Ascending");arrObj.sortBy("-Age").print("Age Descending");

您可能需要将它们转换为小写,以防止混淆。

objs.sort(function (a,b) {
var nameA=a.last_nom.toLowerCase(), nameB=b.last_nom.toLowerCase()
if (nameA < nameB)return -1;if (nameA > nameB)return 1;return 0;  //no sorting
})

示例用法:

objs.sort(sortBy('last_nom'));

脚本:

/*** @description* Returns a function which will sort an* array of objects by the given key.** @param  {String}  key* @param  {Boolean} reverse* @return {Function}*/const sortBy = (key, reverse) => {
// Move smaller items towards the front// or back of the array depending on if// we want to sort the array in reverse// order or not.const moveSmaller = reverse ? 1 : -1;
// Move larger items towards the front// or back of the array depending on if// we want to sort the array in reverse// order or not.const moveLarger = reverse ? -1 : 1;
/*** @param  {*} a* @param  {*} b* @return {Number}*/return (a, b) => {if (a[key] < b[key]) {return moveSmaller;}if (a[key] > b[key]) {return moveLarger;}return 0;};};

根据你的例子,你需要按两个字段(姓氏,名字)排序,而不是一个。你可以使用alasql库在一行中进行排序:

var res = alasql('SELECT * FROM ? ORDER BY last_nom, first_nom',[objs]);

试试这个例子在jsFiddle

使用原型https://github.com/reduardo7/xPrototype/blob/master/README.md#sortbycol1-col2-coln

var o = [{ Name: 'Lazslo', LastName: 'Jamf'     },{ Name: 'Pig',    LastName: 'Bodine'   },{ Name: 'Pirate', LastName: 'Prentice' },{ Name: 'Pag',    LastName: 'Bodine'   }];

// Originalo.each(function (a, b) { console.log(a, b); });/*0 Object {Name: "Lazslo", LastName: "Jamf"}1 Object {Name: "Pig", LastName: "Bodine"}2 Object {Name: "Pirate", LastName: "Prentice"}3 Object {Name: "Pag", LastName: "Bodine"}*/

// Sort By LastName ASC, Name ASCo.sortBy('LastName', 'Name').each(function(a, b) { console.log(a, b); });/*0 Object {Name: "Pag", LastName: "Bodine"}1 Object {Name: "Pig", LastName: "Bodine"}2 Object {Name: "Lazslo", LastName: "Jamf"}3 Object {Name: "Pirate", LastName: "Prentice"}*/

// Sort by LastName ASC and Name ASCo.sortBy('LastName'.asc, 'Name'.asc).each(function(a, b) { console.log(a, b); });/*0 Object {Name: "Pag", LastName: "Bodine"}1 Object {Name: "Pig", LastName: "Bodine"}2 Object {Name: "Lazslo", LastName: "Jamf"}3 Object {Name: "Pirate", LastName: "Prentice"}*/

// Sort by LastName DESC and Name DESCo.sortBy('LastName'.desc, 'Name'.desc).each(function(a, b) { console.log(a, b); });/*0 Object {Name: "Pirate", LastName: "Prentice"}1 Object {Name: "Lazslo", LastName: "Jamf"}2 Object {Name: "Pig", LastName: "Bodine"}3 Object {Name: "Pag", LastName: "Bodine"}*/

// Sort by LastName DESC and Name ASCo.sortBy('LastName'.desc, 'Name'.asc).each(function(a, b) { console.log(a, b); });/*0 Object {Name: "Pirate", LastName: "Prentice"}1 Object {Name: "Lazslo", LastName: "Jamf"}2 Object {Name: "Pag", LastName: "Bodine"}3 Object {Name: "Pig", LastName: "Bodine"}*/

我刚刚增强了埃格·奥兹坎的动态排序以深入对象内部。如果数据看起来像这样:

obj = [{a: { a: 1, b: 2, c: 3 },b: { a: 4, b: 5, c: 6 }},{a: { a: 3, b: 2, c: 1 },b: { a: 6, b: 5, c: 4 }}];

如果你想对a属性进行排序,我认为我的增强非常有帮助。我为这样的对象添加了新功能:

Object.defineProperty(Object.prototype, 'deepVal', {enumerable: false,writable: true,value: function (propertyChain) {var levels = propertyChain.split('.');parent = this;for (var i = 0; i < levels.length; i++) {if (!parent[levels[i]])return undefined;parent = parent[levels[i]];}return parent;}});

并更改了_dynamicSort返回函数:

return function (a,b) {var result = ((a.deepVal(property) > b.deepVal(property)) - (a.deepVal(property) < b.deepVal(property)));return result * sortOrder;}

现在你可以这样按a. a.排序:

obj.sortBy('a.a');

请参阅JSFiddle中的Commplete脚本

排序(更多)复杂的对象数组

由于您可能会遇到像这个数组这样更复杂的数据结构,我将扩展解决方案。

太长别读

是基于的更可插拔的版本,非常可爱的回答

问题

我遇到下面的情况,无法更改它。我也不想暂时展平对象。我也不想使用下划线/洛塔什,主要是出于性能原因和自己实现它的乐趣。

var People = [{Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"},{Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"},{Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"}];

目标

目标是主要按People.Name.name排序,其次按People.Name.surname排序

障碍

现在,在基本解决方案中使用括号表示法来计算要动态排序的属性。不过,在这里,我们也必须动态构造括号表示法,因为你会期望像People['Name.name']这样的东西会起作用-但事实并非如此。

另一方面,简单地做People['Name']['name']是静态的,只允许你向下第1级。

解决方案

这里的主要补充是沿着对象树向下走并确定最后一个叶子的值,您必须指定,以及任何中间叶子。

var People = [{Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"},{Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"},{Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"}];
People.sort(dynamicMultiSort(['Name','name'], ['Name', '-surname']));// Results in...// [ { Name: { name: 'AAA', surname: 'ZZZ' }, Middlename: 'Abrams' },//   { Name: { name: 'Name', surname: 'Surname' }, Middlename: 'JJ' },//   { Name: { name: 'Name', surname: 'AAA' }, Middlename: 'Wars' } ]
// same logic as above, but strong deviation for dynamic propertiesfunction dynamicSort(properties) {var sortOrder = 1;// determine sort order by checking sign of last element of arrayif(properties[properties.length - 1][0] === "-") {sortOrder = -1;// Chop off signproperties[properties.length - 1] = properties[properties.length - 1].substr(1);}return function (a,b) {propertyOfA = recurseObjProp(a, properties)propertyOfB = recurseObjProp(b, properties)var result = (propertyOfA < propertyOfB) ? -1 : (propertyOfA > propertyOfB) ? 1 : 0;return result * sortOrder;};}
/*** Takes an object and recurses down the tree to a target leaf and returns it value* @param  {Object} root - Object to be traversed.* @param  {Array} leafs - Array of downwards traversal. To access the value: {parent:{ child: 'value'}} -> ['parent','child']* @param  {Number} index - Must not be set, since it is implicit.* @return {String|Number}       The property, which is to be compared by sort.*/function recurseObjProp(root, leafs, index) {index ? index : index = 0var upper = root// walk down one levellower = upper[leafs[index]]// Check if last leaf has been hit by having gone one step too far.// If so, return result from last step.if (!lower) {return upper}// Else: recurse!index++// HINT: Bug was here, for not explicitly returning function// https://stackoverflow.com/a/17528613/3580261return recurseObjProp(lower, leafs, index)}
/*** Multi-sort your array by a set of properties* @param {...Array} Arrays to access values in the form of: {parent:{ child: 'value'}} -> ['parent','child']* @return {Number} Number - number for sort algorithm*/function dynamicMultiSort() {var args = Array.prototype.slice.call(arguments); // slight deviation to base
return function (a, b) {var i = 0, result = 0, numberOfProperties = args.length;// REVIEW: slightly verbose; maybe no way around because of `.sort`-'s nature// Consider: `.forEach()`while(result === 0 && i < numberOfProperties) {result = dynamicSort(args[i])(a, b);i++;}return result;}}

示例

工作示例在jsbin

function compare(propName) {return function(a,b) {if (a[propName] < b[propName])return -1;if (a[propName] > b[propName])return 1;return 0;};}
objs.sort(compare("last_nom"));

这是一个简单的问题,不知道为什么人们有这样复杂的解决方案。
一个简单的排序函数(基于快速排序算法):

function sortObjectsArray(objectsArray, sortKey){// Quick Sort:var retVal;
if (1 < objectsArray.length){var pivotIndex = Math.floor((objectsArray.length - 1) / 2);  // middle indexvar pivotItem = objectsArray[pivotIndex];                    // value in the middle indexvar less = [], more = [];
objectsArray.splice(pivotIndex, 1);                          // remove the item in the pivot positionobjectsArray.forEach(function(value, index, array){value[sortKey] <= pivotItem[sortKey] ?                   // compare the 'sortKey' proipertyless.push(value) :more.push(value) ;});
retVal = sortObjectsArray(less, sortKey).concat([pivotItem], sortObjectsArray(more, sortKey));}else{retVal = objectsArray;}
return retVal;}

使用示例:

var myArr =[{ val: 'x', idx: 3 },{ val: 'y', idx: 2 },{ val: 'z', idx: 5 },];myArr = sortObjectsArray(myArr, 'idx');

一个简单的方法:

objs.sort(function(a,b) {return b.last_nom.toLowerCase() < a.last_nom.toLowerCase();});

看到'.toLowerCase()'是防止错误所必需的比较字符串。

在ES6/ES2015或更高版本中,您可以这样做:

objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom));

在ES6/ES2015之前

objs.sort(function(a, b) {return a.last_nom.localeCompare(b.last_nom)});

警告!
使用这个解决方案是不建议,因为它不会导致排序数组。它被留在这里供将来参考,因为这个想法并不罕见。

objs.sort(function(a,b){return b.last_nom>a.last_nom})

我遇到了排序对象数组的问题,随着值优先级的变化,基本上我想按年龄对人民数组进行排序,然后按姓氏-或者只是按姓氏,名称。我认为这是最简单的解决方案相比,另一个答案。

it'通过调用sortPeople(['数组','of','属性'],反向=false来使用)

///////////////////////example array of peoples ///////////////////////
var peoples = [{name: "Zach", surname: "Emergency", age: 1},{name: "Nancy", surname: "Nurse", age: 1},{name: "Ethel", surname: "Emergency", age: 1},{name: "Nina", surname: "Nurse", age: 42},{name: "Anthony", surname: "Emergency", age: 42},{name: "Nina", surname: "Nurse", age: 32},{name: "Ed", surname: "Emergency", age: 28},{name: "Peter", surname: "Physician", age: 58},{name: "Al", surname: "Emergency", age: 58},{name: "Ruth", surname: "Registration", age: 62},{name: "Ed", surname: "Emergency", age: 38},{name: "Tammy", surname: "Triage", age: 29},{name: "Alan", surname: "Emergency", age: 60},{name: "Nina", surname: "Nurse", age: 58}];


//////////////////////// Sorting function /////////////////////function sortPeoples(propertyArr, reverse) {function compare(a,b) {var i=0;while (propertyArr[i]) {if (a[propertyArr[i]] < b[propertyArr[i]])  return -1;if (a[propertyArr[i]] > b[propertyArr[i]])  return 1;i++;}return 0;}peoples.sort(compare);if (reverse){peoples.reverse();}};
////////////////end of sorting method///////////////function printPeoples(){$('#output').html('');peoples.forEach( function(person){$('#output').append(person.surname+" "+person.name+" "+person.age+"<br>");} )}
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script></head><html><body><button onclick="sortPeoples(['surname']); printPeoples()">sort by ONLY by surname ASC results in mess with same name cases</button><br><button onclick="sortPeoples(['surname', 'name'], true); printPeoples()">sort by surname then name DESC</button><br><button onclick="sortPeoples(['age']); printPeoples()">sort by AGE ASC. Same issue as in first case</button><br><button onclick="sortPeoples(['age', 'surname']); printPeoples()">sort by AGE and Surname ASC. Adding second field fixed it.</button><br>        
<div id="output"></div></body></html>

这里有很多很好的答案,但我想指出,它们可以非常简单地扩展以实现更复杂的排序。你唯一要做的就是使用OR运算符来链接比较函数,如下所示:

objs.sort((a,b)=> fn1(a,b) || fn2(a,b) || fn3(a,b) )

其中fn1fn2,…是返回[-1,0,1]的排序函数。这导致“按fn1排序”,“按fn2排序”,这几乎等于SQL中的ORDER BY。

此解决方案基于计算结果为可以转换为true的第一个计算表达式||运算符的行为。

最简单的形式只有一个内联函数,如下所示:

// ORDER BY last_nomobjs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) )

有两个步骤last_nomfirst_nom排序顺序看起来像这样:

// ORDER_BY last_nom, first_nomobjs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) ||a.first_nom.localeCompare(b.first_nom)  )

泛型比较函数可能是这样的:

// ORDER BY <n>let cmp = (a,b,n)=>a[n].localeCompare(b[n])

此功能可以扩展为支持数字字段、大小写敏感性、任意数据类型等。

你可以通过排序优先级链接它们来使用它:

// ORDER_BY last_nom, first_nomobjs.sort((a,b)=> cmp(a,b, "last_nom") || cmp(a,b, "first_nom") )// ORDER_BY last_nom, first_nom DESCobjs.sort((a,b)=> cmp(a,b, "last_nom") || -cmp(a,b, "first_nom") )// ORDER_BY last_nom DESC, first_nom DESCobjs.sort((a,b)=> -cmp(a,b, "last_nom") || -cmp(a,b, "first_nom") )

这里的重点是,采用函数式方法的纯JavaScript可以让您在没有外部库或复杂代码的情况下走很长的路。它也非常有效,因为无需进行字符串解析

还有一个选择:

var someArray = [...];
function generateSortFn(prop, reverse) {return function (a, b) {if (a[prop] < b[prop]) return reverse ? 1 : -1;if (a[prop] > b[prop]) return reverse ? -1 : 1;return 0;};}
someArray.sort(generateSortFn('name', true));

默认情况下升序排序。

// Sort Array of Objects
// Datavar booksArray = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];
// Property to Sort Byvar args = "last_nom";
// Function to Sort the Data by given Propertyfunction sortByProperty(property) {return function (a, b) {var sortStatus = 0,aProp = a[property].toLowerCase(),bProp = b[property].toLowerCase();if (aProp < bProp) {sortStatus = -1;} else if (aProp > bProp) {sortStatus = 1;}return sortStatus;};}
// Implementationvar sortedArray = booksArray.sort(sortByProperty(args));
console.log("sortedArray: " + JSON.stringify(sortedArray) );

控制台日志输出:

"sortedArray:[{"first_nom":"Pig","last_nom":"Bodine"},{"first_nom":"Lazslo","last_nom":"Jamf"},{"first_nom":"Pirate","last_nom":"Prentice"}]"

根据此来源改编:https://web.archive.org/web/20210515081841/http://opnsrce.github.io/code-snippet-how-to-sort-an-array-of-json-objects-by-property

这将根据以字母数字顺序传递给它的属性对两级嵌套数组进行排序。

function sortArrayObjectsByPropAlphaNum(property) {return function (a,b) {var reA = /[^a-zA-Z]/g;var reN = /[^0-9]/g;var aA = a[property].replace(reA, '');var bA = b[property].replace(reA, '');
if(aA === bA) {var aN = parseInt(a[property].replace(reN, ''), 10);var bN = parseInt(b[property].replace(reN, ''), 10);return aN === bN ? 0 : aN > bN ? 1 : -1;} else {return a[property] > b[property] ? 1 : -1;}};}

用法:

objs.sort(utils.sortArrayObjectsByPropAlphaNum('last_nom'));

我知道这个问题太老了,但我没有看到任何类似于我的实现。
此版本基于施瓦茨变换习语

function sortByAttribute(array, ...attrs) {// generate an array of predicate-objects contains// property getter, and descending indicatorlet predicates = attrs.map(pred => {let descending = pred.charAt(0) === '-' ? -1 : 1;pred = pred.replace(/^-/, '');return {getter: o => o[pred],descend: descending};});// schwartzian transform idiom implementation. aka: "decorate-sort-undecorate"return array.map(item => {return {src: item,compareValues: predicates.map(predicate => predicate.getter(item))};}).sort((o1, o2) => {let i = -1, result = 0;while (++i < predicates.length) {if (o1.compareValues[i] < o2.compareValues[i]) result = -1;if (o1.compareValues[i] > o2.compareValues[i]) result = 1;if (result *= predicates[i].descend) break;}return result;}).map(item => item.src);}

下面是一个如何使用它的例子:

let games = [{ name: 'Mashraki',          rating: 4.21 },{ name: 'Hill Climb Racing', rating: 3.88 },{ name: 'Angry Birds Space', rating: 3.88 },{ name: 'Badland',           rating: 4.33 }];
// sort by one attributeconsole.log(sortByAttribute(games, 'name'));// sort by mupltiple attributesconsole.log(sortByAttribute(games, '-rating', 'name'));

所以这里有一个排序算法,它可以在任何类型的对象数组中以任何顺序排序,而不受数据类型比较(即数字,字符串)的限制

function smoothSort(items,prop,reverse) {var length = items.length;for (var i = (length - 1); i >= 0; i--) {//Number of passesfor (var j = (length - i); j > 0; j--) {//Compare the adjacent positionsif(reverse){if (items[j][prop] > items[j - 1][prop]) {//Swap the numbersvar tmp = items[j];items[j] = items[j - 1];items[j - 1] = tmp;}}
if(!reverse){if (items[j][prop] < items[j - 1][prop]) {//Swap the numbersvar tmp = items[j];items[j] = items[j - 1];items[j - 1] = tmp;}}}}
return items;}
  • 第一个参数项目是对象数组,

  • prop是要对其进行排序的对象的键,

  • 反向是一个布尔参数,如果为true,则返回升序,如果为false,则返回降序。

使用Ramda,

npm安装ramda

import R from 'ramda'var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];var ascendingSortedObjs = R.sortBy(R.prop('last_nom'), objs)var descendingSortedObjs = R.reverse(ascendingSortedObjs)

我将给你一个实现选择排序算法的解决方案,它简单有效

var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];

function selection_Sort(num) {//console.log(num);var temp, index;for (var i = 0; i <= num.length - 1; i++) {index = i;for (var j = i + 1; j <= num.length - 1; j++) {// you can use first_nom/last_nom,any way you choose to sort
if (num[j]. last_nom < num[index]. last_nom) {index = j;}}
//below is the swapping parttemp = num[i]. last_nom;num[i]. last_nom = num[index]. last_nom;num[index]. last_nom = temp;};console.log(num);return num;}selection_Sort(objs);

很高兴看到这么好的答案

Lodash.jsUnderscore.js的超集)

最好不要为每一个简单的逻辑添加一个框架,但是依靠经过良好测试的实用框架可以加快开发速度并减少错误的数量。

Lodash生成了非常干净的代码并推广了更函数式编程的风格。一瞥就清楚了代码的意图是什么。

OP的问题可以简单地解决为:

const sortedObjs = _.sortBy(objs, 'last_nom');

更多信息?例如。我们有以下嵌套对象:

const users = [  { 'user': {'name':'fred', 'age': 48}},  { 'user': {'name':'barney', 'age': 36 }},  { 'user': {'name':'wilma'}},  { 'user': {'name':'betty', 'age': 32}}];

我们现在可以使用_属性简写user.age来指定应该匹配的属性的路径。我们将按嵌套的age属性对用户对象进行排序。是的,它允许嵌套的属性匹配!

const sortedObjs = _.sortBy(users, ['user.age']);

要反转吗?没问题。使用_反转

const sortedObjs = _.reverse(_.sortBy(users, ['user.age']));

想要使用合并两者吗?

const { chain } = require('lodash');const sortedObjs = chain(users).sortBy('user.age').reverse().value();

或者你什么时候更喜欢而不是链

const { flow, reverse, sortBy } = require('lodash/fp');const sortedObjs = flow([sortBy('user.age'), reverse])(users);

旧答案不正确:

arr.sort((a, b) => a.name > b.name)

更新

来自博尚的评论:

arr.sort((a, b) => a.name < b.name ? -1 : (a.name > b.name ? 1 : 0))

更具可读性的格式:

arr.sort((a, b) => {if (a.name < b.name) return -1return a.name > b.name ? 1 : 0})

没有嵌套三元:

arr.sort((a, b) => a.name < b.name ? - 1 : Number(a.name > b.name))

说明:Number()true转换为1false转换为0

给出最初的例子:

var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];

按多个字段排序:

objs.sort(function(left, right) {var last_nom_order = left.last_nom.localeCompare(right.last_nom);var first_nom_order = left.first_nom.localeCompare(right.first_nom);return last_nom_order || first_nom_order;});

备注

  • a.localeCompare(b)普遍支持,如果a<ba==ba>b分别返回-1,0,1。
  • 最后一行中的||表示last_nom优先于first_nom
  • 减法适用于数字字段:var age_order = left.age - right.age;
  • 否定为反向顺序,return -last_nom_order || -first_nom_order || -age_order;

用豆泥或下划线,这是小菜一碟

> const sortedList = _.orderBy(objs, [last_nom], [asc]); // asc or desc

一个简单的函数,按属性对对象数组进行排序

function sortArray(array, property, direction) {direction = direction || 1;array.sort(function compare(a, b) {let comparison = 0;if (a[property] > b[property]) {comparison = 1 * direction;} else if (a[property] < b[property]) {comparison = -1 * direction;}return comparison;});return array; // Chainable}

用法:

var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];
sortArray(objs, "last_nom"); // AscsortArray(objs, "last_nom", -1); // Desc

方式一:

您可以使用Underscore.js。首先导入下划线。

 import * as _ from 'underscore';let SortedObjs = _.sortBy(objs, 'last_nom');

方法2:使用比较功能。

function compare(first, second) {if (first.last_nom < second.last_nom)return -1;if (first.last_nom > second.last_nom)return 1;return 0;}
objs.sort(compare);

截至2018年,有一个更短、更优雅的解决方案。只需使用。Array.prototype.sort()

示例:

var items = [{ name: 'Edward', value: 21 },{ name: 'Sharpe', value: 37 },{ name: 'And', value: 45 },{ name: 'The', value: -12 },{ name: 'Magnetic', value: 13 },{ name: 'Zeros', value: 37 }];
// sort by valueitems.sort(function (a, b) {return a.value - b.value;});

它为我工作。在这里它将保持未定义到最后。

 function sort(items, property, direction) {
function compare(a, b) {if(!a[property] && !b[property]) {return 0;} else if(a[property] && !b[property]) {return -1;} else if(!a[property] && b[property]) {return 1;} else {const value1 = a[property].toString().toUpperCase(); // ignore upper and lowercaseconst value2 = b[property].toString().toUpperCase(); // ignore upper and lowercaseif (value1 < value2) {return direction === 0 ? -1 : 1;} else if (value1 > value2) {return direction === 0 ? 1 : -1;} else {return 0;}        
}}    
return items.sort(compare);}   
var items = [{ name: 'Edward', value: 21 },{ name: 'Sharpe', value: 37 },{ name: 'And', value: 45 },{ name: 'The', value: -12 },{ name: undefined, value: -12 },{ name: 'Magnetic', value: 13 },{ name: 'Zeros', value: 37 }];console.log('Ascending Order:- ');console.log(sort(items, 'name', 0));console.log('Decending Order:- ');console.log(sort(items, 'name', 1));    

我还没有看到这种特殊的方法,所以这里有一个我喜欢使用的简洁的比较方法,适用于stringnumber类型:

const objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];
const sortBy = fn => {const cmp = (a, b) => -(a < b) || +(a > b);return (a, b) => cmp(fn(a), fn(b));};
const getLastName = o => o.last_nom;const sortByLastName = sortBy(getLastName);
objs.sort(sortByLastName);console.log(objs.map(getLastName));

解释sortBy()

sortBy()接受一个fn,它从对象中选择一个值用于比较,并返回一个可以传递给#2的函数。在这个例子中,我们比较o.last_nom。每当我们收到两个对象时,例如

a = { first_nom: 'Lazslo', last_nom: 'Jamf' }b = { first_nom: 'Pig', last_nom: 'Bodine' }

我们将它们与(a, b) => cmp(fn(a), fn(b))进行比较。鉴于

fn = o => o.last_nom

我们可以将比较函数扩展为(a, b) => cmp(a.last_nom, b.last_nom)。由于逻辑或(#1)在JavaScript中的工作方式,cmp(a.last_nom, b.last_nom)相当于

if (a.last_nom < b.last_nom) return -1;if (a.last_nom > b.last_nom) return 1;return 0;

顺便说一句,这在其他语言中被称为三路比较“宇宙飞船”(#0)操作符

最后,这是不使用箭头函数的ES5兼容语法:

var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];
function sortBy(fn) {function cmp(a, b) { return -(a < b) || +(a > b); }return function (a, b) { return cmp(fn(a), fn(b)); };}
function getLastName(o) { return o.last_nom; }var sortByLastName = sortBy(getLastName);
objs.sort(sortByLastName);console.log(objs.map(getLastName));

您可以使用最简单的方法:Lodash

https://lodash.com/docs/4.17.10#orderBy

此方法类似于_.sortBy,只是它允许指定要排序的迭代的排序顺序。如果未指定顺序,则所有值按升序排序。否则,指定降序的“desc”或升序的“asc”为相应值的升序排序。

论点

集合(Array|Object):要迭代的集合。[iteratees=[_]](Array[]|Function[]|Object[]|string[]):要排序的迭代对象。[order](string[]):迭代器的排序顺序。

退货

(Array):返回新的排序数组。


var _ = require('lodash');var homes = [{"h_id":"3","city":"Dallas","state":"TX","zip":"75201","price":"162500"},{"h_id":"4","city":"Bevery Hills","state":"CA","zip":"90210","price":"319250"},{"h_id":"6","city":"Dallas","state":"TX","zip":"75000","price":"556699"},{"h_id":"5","city":"New York","state":"NY","zip":"00010","price":"962500"}];    
_.orderBy(homes, ['city', 'state', 'zip'], ['asc', 'desc', 'asc']);

如果你有嵌套对象

const objs = [{first_nom: 'Lazslo',last_nom: 'Jamf',moreDetails: {age: 20}}, {first_nom: 'Pig',last_nom: 'Bodine',moreDetails: {age: 21}}, {first_nom: 'Pirate',last_nom: 'Prentice',moreDetails: {age: 22}}];
nestedSort = (prop1, prop2 = null, direction = 'asc') => (e1, e2) => {const a = prop2 ? e1[prop1][prop2] : e1[prop1],b = prop2 ? e2[prop1][prop2] : e2[prop1],sortOrder = direction === "asc" ? 1 : -1return (a < b) ? -sortOrder : (a > b) ? sortOrder : 0;}

并称之为

objs.sort(nestedSort("last_nom"));objs.sort(nestedSort("last_nom", null, "desc"));objs.sort(nestedSort("moreDetails", "age"));objs.sort(nestedSort("moreDetails", "age", "desc"));

TypeScript中编程时也可以制作动态排序函数,但在这种情况下,类型变得更加棘手。

function sortByKey<O>(key: keyof O, decending: boolean = false): (a: O, b: O) => number {const order = decending ? -1 : 1;return (a, b): number => {const valA = a[key];const valB = b[key];if (valA < valB) {return -order;} else if (valA > valB) {return order;} else {return 0;}}}

这可以在TypeScript中使用如下:

const test = [{id: 0,},{id: 2,}]
test.sort(sortByKey('id')) // OKtest.sort(sortByKey('id1')) // ERRORtest.sort(sortByKey('')) // ERROR

这个排序功能可以用于所有对象排序,

  • 对象

  • 深度对象

  • 数字数组

您还可以通过传递1,-1作为参数来进行排序或降序排序

Object.defineProperty(Object.prototype, 'deepVal', {enumerable: false,writable: true,value: function (propertyChain) {var levels = propertyChain.split('.');parent = this;for (var i = 0; i < levels.length; i++) {if (!parent[levels[i]])return undefined;parent = parent[levels[i]];}return parent;}});

function dynamicSortAll(property,sortOrders=1) {
/**default sorting will be ascending order if you need descending ordersording you have to pass -1 as param**/
var sortOrder = sortOrders;   
return function (a,b) {
var result =(property? ((a.deepVal(property) > b.deepVal(property)) ? 1 : (a.deepVal(property) < b.deepVal(property)) ? -1 : 0) :((a > b) ? 1 : (a < b) ? -1 : 0))		
return result * sortOrder;		
   
}}
deepObj = [{a: { a: 1, b: 2, c: 3 },b: { a: 4, b: 5, c: 6 }},{a: { a: 3, b: 2, c: 1 },b: { a: 6, b: 5, c: 4 }}];
let deepobjResult=deepObj.sort(dynamicSortAll('a.a',1))console.log('deepobjResult :'+ JSON.stringify(deepobjResult))var obj = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];let objResult=obj.sort(dynamicSortAll('last_nom',1))console.log('objResult :'+ JSON.stringify(objResult))
var numericObj=[1,2,3,4,5,6]
let numResult=numericObj.sort(dynamicSortAll(null,-1))console.log('numResult :'+ JSON.stringify(numResult))
let stringSortResult='helloworld'.split('').sort(dynamicSortAll(null,1))
console.log('stringSortResult:'+ JSON.stringify(stringSortResult))
let uniqueStringOrger=[...new Set(stringSortResult)];console.log('uniqueStringOrger:'+ JSON.stringify(uniqueStringOrger))

她的一个函数,您可以使用它来按多个对象对列表进行排序,如果第一个对象相等,第二个顺序将被用作后备。如果可能,空值也应被忽略以后备顺序。

function sortObjects(list, orderBy){list.sort(function(a, b){let byIndex = 0;let order = orderBy[byIndex];while(!a[order.by] || !b[order.by] || a[order.by] === b[order.by]){byIndex++;if(byIndex >= orderBy.length){break;}order = orderBy[byIndex];}if(!a[order.by] || !b[order.by] || a[order.by] === b[order.by]){return false;}if(order.desc){return a[order.by] < b[order.by];}return a[order.by] > b[order.by];});return list;}

用法:

var objs = [{a: 10, b: 20, c: 30},{a: 30, b: 10, c: 20},{a: 20, b: 10, c: 30},];
sortObjectList(objs, [{by: 'a'}]);[{a: 10, b: 20, c: 30},{a: 20, b: 10, c: 30},{a: 30, b: 10, c: 20},]
sortObjectList(objs, [{by: 'a', desc: true}]);[{a: 30, b: 10, c: 20},{a: 20, b: 10, c: 30},{a: 10, b: 20, c: 30},]
sortObjectList(objs, [{by: 'b', desc: true}, {by: 'c'}]);[{a: 10, b: 20, c: 30},{a: 30, b: 10, c: 20},{a: 20, b: 10, c: 30},]

另一个例子:

var objs = [{a: 5, b: 5},{a: 10, b: 15},{a: 15, b: 25},{b: 10},{b: 20},{a: 10, b: 30},{a: 10, b: 12},];
sortObjectList(objs, [{by: 'a'}, {by: 'b'}]);[{a: 5, b: 5},{b: 10},{a: 10, b: 12},{a: 10, b: 15},{b: 20},{a: 10, b: 30},{a: 15, b: 25},]

这是我对此的看法:

order参数是可选的,默认为“ASC”升序。

工作在重音字符而且不区分大小写

注:它排序并返回原始数组。

function sanitizeToSort(str) {return str.normalize('NFD')                   // REMOVE ACCENTED AND DIACRITICS.replace(/[\u0300-\u036f]/g,'')     // REMOVE ACCENTED AND DIACRITICS.toLowerCase()                      // SORT WILL BE CASE INSENSITIVE;}
function sortByProperty(arr, property, order="ASC") {arr.forEach((item) => item.tempProp = sanitizeToSort(item[property]));arr.sort((a,b) => order === "ASC" ?a.tempProp > b.tempProp ?  1 : a.tempProp < b.tempProp ? -1 : 0: a.tempProp > b.tempProp ? -1 : a.tempProp < b.tempProp ?  1 : 0);arr.forEach((item) => delete item.tempProp);return arr;}

SNIPPET

function sanitizeToSort(str) {return str.normalize('NFD')                   // REMOVE ACCENTED CHARS.replace(/[\u0300-\u036f]/g,'')     // REMOVE DIACRITICS.toLowerCase();}
function sortByProperty(arr, property, order="ASC") {arr.forEach((item) => item.tempProp = sanitizeToSort(item[property]));arr.sort((a,b) => order === "ASC" ?a.tempProp > b.tempProp ?  1 : a.tempProp < b.tempProp ? -1 : 0: a.tempProp > b.tempProp ? -1 : a.tempProp < b.tempProp ?  1 : 0);arr.forEach((item) => delete item.tempProp);return arr;}
const rockStars = [{ name: "Axl",lastname: "Rose" },{ name: "Elthon",lastname: "John" },{ name: "Paul",lastname: "McCartney" },{ name: "Lou",lastname: "Reed" },{ name: "freddie",             // WORKS ON LOWER/UPPER CASElastname: "mercury" },{ name: "Ámy",                 // WORKS ON ACCENTED CHARS TOOlastname: "winehouse"}  
];
sortByProperty(rockStars,"name");
console.log("Ordered by name A-Z:");rockStars.forEach((item) => console.log(item.name + " " + item.lastname));
sortByProperty(rockStars,"lastname","DESC");
console.log("\nOrdered by lastname Z-A:");rockStars.forEach((item) => console.log(item.lastname + ", " + item.name));

试试这个,

UPTO ES5
//Ascending Sortitems.sort(function (a, b) {return a.value - b.value;});

//Descending Sortitems.sort(function (a, b) {return b.value - a.value;});

IN ES6 & above:
// Ascending sortitems.sort((a, b) => a.value - b.value);
// Descending Sortitems.sort((a, b) => b.value - a.value);

您可以使用可重用的排序函数。

Array.prototype.order = function (prop, methods = {}) {if (prop?.constructor == Object) {methods = prop;prop = null;}const [orderType_a, orderType_b] = methods.reverse ? [1, -1] : [-1, 1];
const $ = x => prop? methods.insensitive? String(x[prop]).toLowerCase(): x[prop]: methods.insensitive? String(x).toLowerCase(): x;
const fn = (a, b) => $(a) < $(b) ? orderType_a : $(b) < $(a) ? orderType_b : 0;return this.sort(fn);};

它可用于对数组
中的数组对象进行排序。

let items = [{ x: "Z" }, 3, "1", "0", 2, { x: "a" }, { x: 0 }];items.order("x", { insensitive: 1 })// [ { x: 0 }, { x: 'a' }, 3, '1', '0', 2, { x: 'Z' } ].order({ reverse: 1 })// [ { x: 0 }, { x: 'a' }, 3, 2, { x: 'Z' }, '1', '0' ].sort(x => typeof x == "string" || typeof x == "number" ? -1 : 0)// [ '0', '1', 2, 3, { x: 0 }, { x: 'a' }, { x: 'Z' } ]

1nd(可选)>对数组中包含的对象进行排序。
2是方法>{ reverse: any, insensitive: any }

基于这个优秀的教程,我想开发Vlad Bezden回答并解释为什么#0strA > strB这样的标准comarison方法更好。让我们运行这个例子

console.log( 'Österreich' > 'Zealand' );  // We expect falseconsole.log( 'a' > 'Z' );                 // We expect false

原因是在JS中所有字符串都使用UTF-16

let str = '';
// order of characters in JSfor (let i = 65; i <= 220; i++) {str += String.fromCodePoint(i); // code to character}
console.log(str);

大写字母先走(有小代码),然后是小字母,然后是字符Ö(在z之后)。这就是我们在第一个片段中得到true的原因-因为运算符>比较字符代码。

正如你所看到的,比较不同语言中的字符是一项不平凡的任务——但幸运的是,现代浏览器支持国际化标准ECMA-402。所以在JS中,我们有strA.localeCompare(strB)来完成这项工作(-1意味着strA小于strB;1意味着相反;0意味着相等)

console.log( 'Österreich'.localeCompare('Zealand') ); // We expect -1console.log( 'a'.localeCompare('Z') );                // We expect -1

我想补充一下,localeCompare支持两个参数:语言和附加规则

var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' },{ first_nom: 'Test',   last_nom: 'jamf'     }];
objs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom,'en',{sensitivity:'case'}))
console.log(objs);
// in '>' comparison 'Jamf' will NOT be next to 'jamf'

简单的回答:

objs.sort((a,b)=>a.last_nom.localeCompare(b.last_nom))

详情:

今天它非常简单,您可以将字符串与localeCompare进行比较。正如Mozilla Doc所说:

localeCompare()方法返回一个数字,指示是否引用字符串来自beforeafteris the same as the given string in sort order

    //example1:console.log("aaa".localeCompare("aab")); //-1console.log("aaa".localeCompare("aaa")); //0console.log("aab".localeCompare("aaa")); //1
//example2:const a = 'réservé'; // with accents, lowercaseconst b = 'RESERVE'; // no accents, uppercase
console.log(a.localeCompare(b));// expected output: 1console.log(a.localeCompare(b, 'en', { sensitivity: 'base' }));// expected output: 0

有关更多详细信息,请参阅Mozilla文档#0

对于fp-holics:

const objectSorter = (p)=>(a,b)=>((a,b)=>a>b?1:a<b?-1:0)(a[p], b[p]);objs.sort(objectSorter('first_nom'));

使用JavaScriptsort方法

#0方法可以修改为使用比较函数对数字、字符串甚至对象数组进行排序。

比较函数作为可选参数传递给排序方法。

此比较函数接受2个参数,通常称为一个b。基于这两个参数,您可以修改排序方法以按需工作。

  1. 如果比较函数返回小于0,则sort()方法将一个排序为低于b的索引。简单地说,a将排在b之前。
  2. 如果比较函数返回等于0,则sort()方法保持元素位置不变。
  3. 如果比较函数返回大于0,则sort()方法将一个排序为大于b的索引。简单地一个将在b之后。

使用上述概念应用于您的对象,其中一个将是您的对象属性。

var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf' },{ first_nom: 'Pig', last_nom: 'Bodine' },{ first_nom: 'Pirate', last_nom: 'Prentice' }];function compare(a, b) {if (a.last_nom > b.last_nom) return 1;if (a.last_nom < b.last_nom) return -1;return 0;}objs.sort(compare);console.log(objs)// for better look use console.table(objs)
输出

我一直在各种项目中使用这个实用程序,它工作得很好。它也非常模块化:

  • 传递密钥的名称进行排序
  • 选择排序是上升还是下降

sortArrayOfObjsByKeyUtil.js

// Sort array of objects by key// ------------------------------------------------------------const sortArrayOfObjsByKey = (array, key, ascdesc) =>array.sort((a, b) => {const x = a[key];const y = b[key];if (ascdesc === 'asc') {return x < y ? -1 : x > y ? 1 : 0;}if (ascdesc === 'desc') {return x > y ? -1 : x < y ? 1 : 0;}return null;});

sortArrayOfObjsByKeyUtil.test.js

import sortArrayOfObjsByKey from './sortArrayOfObjsByKeyUtil';
const unsortedArray = [{_id: '3df55221-ce5c-4147-8e14-32effede6133',title: 'Netlife Design',address: {PostalAddress: {streetAddress: 'Youngstorget 3',addressLocality: 'Oslo',addressRegion: null,postalCode: '0181',addressCountry: 'Norway',},},geopoint: { lat: 59.914322, lng: 10.749272 },},{_id: 'cd00459f-3755-49f1-8847-66591ef935b2',title: 'Home',address: {PostalAddress: {streetAddress: 'Stockfleths gate 58A',addressLocality: 'Oslo',addressRegion: null,postalCode: '0461',addressCountry: 'Norway',},},geopoint: { lat: 59.937316, lng: 10.751862 },},];
const sortedArray = [{_id: 'cd00459f-3755-49f1-8847-66591ef935b2',title: 'Home',address: {PostalAddress: {streetAddress: 'Stockfleths gate 58A',addressLocality: 'Oslo',addressRegion: null,postalCode: '0461',addressCountry: 'Norway',},},geopoint: { lat: 59.937316, lng: 10.751862 },},{_id: '3df55221-ce5c-4147-8e14-32effede6133',title: 'Netlife Design',address: {PostalAddress: {streetAddress: 'Youngstorget 3',addressLocality: 'Oslo',addressRegion: null,postalCode: '0181',addressCountry: 'Norway',},},geopoint: { lat: 59.914322, lng: 10.749272 },},];
describe('sortArrayOfObjsByKey', () => {it(`sort array by 'title' key, ascending`, () => {const testInput = sortArrayOfObjsByKey(unsortedArray, 'title', 'asc');const testOutput = sortedArray;expect(testInput).toEqual(testOutput);});});

你为什么不写短代码?

objs.sort((a, b) => a.last_nom > b.last_nom ? 1 : -1)
//Try this way

let objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];const compareBylastNom = (a, b) => {// converting to uppercase to have case-insensitive comparisonconst name1 = a.last_nom.toUpperCase();const name2 = b.last_nom.toUpperCase();    
let comparison = 0;    
if (name1 > name2) {comparison = 1;} else if (name1 < name2) {comparison = -1;}return comparison;}console.log(objs.sort(compareBylastNom));

区分大小写

arr.sort((a, b) => a.name > b.name ? 1 : -1);

不区分大小写

arr.sort((a, b) => a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1);

有用说明

如果顺序没有变化(在相同字符串的情况下),则条件>将失败并返回-1。但如果字符串相同,则返回1或-1将导致正确的输出

另一种选择可能是使用>=运算符而不是>


var objs = [{ first_nom: 'Lazslo', last_nom: 'Jamf'     },{ first_nom: 'Pig',    last_nom: 'Bodine'   },{ first_nom: 'Pirate', last_nom: 'Prentice' }];

// Define a couple of sorting callback functions, one with hardcoded sort key and the other with an argument sort keyconst sorter1 = (a, b) => a.last_nom.toLowerCase() > b.last_nom.toLowerCase() ? 1 : -1;const sorter2 = (sortBy) => (a, b) => a[sortBy].toLowerCase() > b[sortBy].toLowerCase() ? 1 : -1;
objs.sort(sorter1);console.log("Using sorter1 - Hardcoded sort property last_name", objs);
objs.sort(sorter2('first_nom'));console.log("Using sorter2 - passed param sortBy='first_nom'", objs);
objs.sort(sorter2('last_nom'));console.log("Using sorter2 - passed param sortBy='last_nom'", objs);

我知道已经有很多答案了,包括那些使用localeCompare的答案,但是如果你出于某种原因不想/不能使用localeCompare,我建议你使用这个解决方案而不是三元运算符解决方案:

objects.sort((a, b) => (a.name > b.name) - (a.name < b.name));

也许有人会说这段代码做的事情不明显,但在我看来,三元运算符更糟糕。如果一个三元运算符足够易读,那么两个三元运算符一个嵌入到另一个中——真的很难阅读而且很难看。只有两个比较运算符和一个减号运算符的一行代码阅读和推理都非常简单。

当您想要自然排序(即1,2,10,11,111)时,针对特定情况使用#0排序对象。

const files = [{name: "1.mp3", size: 123},{name: "10.mp3", size: 456},{name: "100.mp3", size: 789},{name: "11.mp3", size: 123},{name: "111.mp3", size: 456},{name: "2.mp3", size: 789},];
const naturalCollator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
files.sort((a, b) => naturalCollator.compare(a.name, b.name));
console.log(files);

浏览器支持Intl.Collator

let propName = 'last_nom';
let sorted_obj = objs.sort((a,b) => {if(a[propName] > b[propName]) {return 1;}if (a[propName] < b[propName]) {return -1;}return 0;}
//This works because the js built-in sort function allows us to define our//own way of sorting, this funny looking function is simply telling `sort` how to//determine what is larger.//We can use `if(a[propName] > b[propName])` because string comparison is already built into JS//if you try console.log('a' > 'z' ? 'a' : 'z')//the output will be 'z' as 'a' is not greater than 'z'

我会像他那样做:

[...objs].sort((a, b) => a.last_nom.localeCompare(b.last_nom))