在JavaScript中按string属性值sorting对象数组

我有一个JavaScript对象的数组:

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

我怎样才能sorting他们在JavaScript的last_nom的价值?

我知道sort(a,b) ,但似乎只能用于string和数字。 我需要添加一个toString方法到我的对象?

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

 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(function(a,b) {return (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0);} ); 

您还可以创build一个dynamicsorting函数,按您传递的值sorting对象:

 function dynamicSort(property) { var sortOrder = 1; if(property[0] === "-") { sortOrder = -1; property = property.substr(1); } return function (a,b) { 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")); 

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

多个参数

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

 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")); 

将其添加到原型

(下面的实现是从Mike R的答案中得到的启发)

我不build议更改本地对象原型,只是为了给出一个例子,以便您可以在自己的对象上实现它 (对于支持它的环境,也可以使用Object.defineProperty ,如下一节所示,至less不具有可枚举的负面效应,如最后一部分所述)

原型实现将如下所示( 这是一个工作示例 ):

 //Don't just copy-paste this code. You will break the "for-in" loops !function() { function _dynamicSortMultiple(attr) { /* dynamicSortMultiple function body comes here */ } function _dynamicSort(property) { /* dynamicSort function body comes here */ } Array.prototype.sortBy = function() { return this.sort(_dynamicSortMultiple.apply(null, arguments)); } }(); 

添加到原型的“确定”方法

如果你的目标是IE9以上 ,就像我之前提到的那样,使用Object.defineProperty就像这样( 工作示例 ):

 //Won't work below IE9, but totally safe otherwise !function() { function _dynamicSortMultiple(attr) { /* dynamicSortMultiple function body comes here */ } function _dynamicSort(property) { /* dynamicSort function body comes here */ } Object.defineProperty(Array.prototype, "sortBy", { enumerable: false, writable: true, value: function() { return this.sort(_dynamicSortMultiple.apply(null, arguments)); } }); }(); 

这可以是一个可以接受的妥协,直到绑定操作符到达。

所有这些原型乐趣使这个:

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

你应该阅读这个

如果您使用直接原型访问方法(Object.defineProperty是好的)和其他代码不检查hasOwnProperty ,小猫死亡! 好吧,说实话,没有任何损害任何小猫真的,但可能会破坏,你的团队中的每个其他开发人员会恨你:

邪恶

看到最后的“SortBy”? 是啊。 不酷。 尽可能使用Object.defineProperty,否则保持Array.prototype不变。

underscore.js

使用下划线,其小而真棒…

sortBy_.sortBy(list,iterator,[context])返回列表的一个有序副本,按迭代器运行每个值的结果按升序排列。 迭代器也可以是要sorting的属性的string名称(例如,长度)。

 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' ); 

不要理解为什么人们如此复杂:

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

对于更严格的引擎:

 objs.sort(function(a, b){ return a.last_nom == b.last_nom ? 0 : +(a.last_nom > b.last_nom) || -1; }); 

交换操作员使其按字母顺序sorting。

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

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

如果你有姓氏重复,你可以用名字sorting,

 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; }); 

使用原型inheritance简单而快速地解决这个问题:

 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"}] 

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

您可以使用自定义的toString()方法(由默认比较函数调用toString()创build一个对象types,而不是使用自定义比较函数:

 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(); 

sorting(更多)复杂的对象数组

既然你可能遇到更复杂的数据结构,比如这个数组,我会扩展解决scheme。

TL; DR

基于@ ege-Özcan的可插拔版本是非常可爱的答案 。

问题

我遇到下面,无法改变它。 我也不想暂时把物体弄平。 我也不想使用下划线/ lodash,主要是出于性能的原因以及自己实现它的乐趣。

 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.namesorting,然后由People.Name.namesorting

障碍

现在,基本解决scheme使用括号表示法来计算要dynamicsorting的属性。 在这里,虽然,我们将不得不dynamic地构造括号记号,因为你会期望一些像People['Name.name']会工作 – 哪一个不会。

简单地做人People['Name']['name'] ,而另一方面,是静态的,只允许你下降到第n级。

这里的主要添加将是沿着对象树走下去,并确定最后一个叶的值,你必须指定,以及任何中介叶。

 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 properties function dynamicSort(properties) { var sortOrder = 1; // determine sort order by checking sign of last element of array if(properties[properties.length - 1][0] === "-") { sortOrder = -1; // Chop off sign properties[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 = 0 var upper = root // walk down one level lower = 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/3580261 return 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上工作的例子

我知道这个问题太旧了,但是我没有看到类似于我的任何实现。
这个版本是基于Schwartzian变换成语 。

 function sortByAttribute(array, ...attrs) { // generate an array of predicate-objects contains // property getter, and descending indicator let 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: 'Pako', 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 attribute console.log(sortByAttribute(games, 'name')); // sort by mupltiple attributes console.log(sortByAttribute(games, '-rating', 'name')); 

用法示例:

 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} */ function 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. var 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. var moveLarger = reverse ? -1 : 1; /** * @param {*} a * @param {*} b * @return {Number} */ return function(a, b) { if (a[key] < b[key]) { return moveSmaller; } if (a[key] > b[key]) { return moveLarger; } return 0; }; } 

一个简单的方法:

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

看到'.toLowerCase()'是必要的,以防止比较string的错误。

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

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

其中fn1fn2 ,…是返回[-1,0,1]的sorting函数。 这导致了“按fn1sorting”,“按fn2sorting”,这与SQL中的ORDER BY非常相似。

该解决scheme基于||的行为 运算符,其评估为可以转换为真的第一个评估expression式 。

最简单的forms只有一个这样的内联函数:

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

first_nomsorting顺序看起来像这样:

 // ORDER_BY last_nom, first_nom objs.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]) 

这个函数可以扩展为支持数字字段,大小写敏感性,任意数据types等。

你可以用它们来按顺序链接它们:

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

这里的要点是,纯粹的JavaScript与function的方法可以采取你很长一段路,没有外部库或复杂的代码。 这也是非常有效的,因为没有stringparsing必须完成

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

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

尝试在jsFiddle这个例子。

EgeÖzcan代码的额外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的dynamic解决scheme和Vinay的想法,你会得到一个很好的解决scheme:

 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)); } 

用法:

 // Utility for printing objects Array.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 data var 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 Tests arrObj.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){return b.last_nom>a.last_nom}) 

还有一个select:

 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)); 

按照默认升序排列。

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

 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 }) 
 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")); 

我只是增强了EgeÖzcan的dynamicsorting来深入物体内部。 如果数据如下所示:

 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 } }]; 

如果你想sorting它的财产,我认为我的增强帮助很好。 我为这样的对象添加新的function:

 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; } 

现在你可以通过这种方式进行sorting:

 obj.sortBy('a.a'); 

请参阅JSFiddle中的完整脚本

这是一个简单的问题,不知道为什么人们有这样复杂的解决scheme。
一个简单的sortingfunction(基于快速sortingalgorithm):

 function sortObjectsArray(objectsArray, sortKey) { // Quick Sort: var retVal; if (1 < objectsArray.length) { var pivotIndex = Math.floor((objectsArray.length - 1) / 2); // middle index var pivotItem = objectsArray[pivotIndex]; // value in the middle index var less = [], more = []; objectsArray.splice(pivotIndex, 1); // remove the item in the pivot position objectsArray.forEach(function(value, index, array) { value[sortKey] <= pivotItem[sortKey] ? // compare the 'sortKey' proiperty less.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'); 

Lodash.js ( Underscore.js的超集)

最好不要为每一个简单的逻辑添加一个框架,而是依靠一个经过充分testing的实用框架,加快开发速度,减less写入的bug数量并不丢人。

Lodash生成非常干净的代码,并提供更多function的编程风格,从而减less错误。 在一瞥中,变得清楚代码是什么意图。

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

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

更多信息? 比如我们有下面的嵌套对象:

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

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

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

想要颠倒? 没问题。 使用_.reverse 。

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

想要结合使用链接而不是?

 var sortedObjs = _.chain(users).sortBy('user.age').reverse().value(); 

使用xPrototype : 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' } ]; // Original o.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 ASC o.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 ASC o.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 DESC o.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 ASC o.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"} */ 

使用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) 

我进入sorting对象数组的问题,改变值的优先级,基本上我想按他们的年龄,然后通过姓氏或姓氏,姓名sorting人民arrays。 我认为这是最简单的解决办法相比,另一个答案。

它通过调用sortPeoples(['array','of','properties'],reverse = 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> 

所以这里有一个sortingalgorithm,可以按任意顺序对任意types的数组进行sorting,而不受数据types比较的限制(即Number,String)

 function smoothSort(items,prop,reverse) { var length = items.length; for (var i = (length - 1); i >= 0; i--) { //Number of passes for (var j = (length - i); j > 0; j--) { //Compare the adjacent positions if(reverse){ if (items[j][prop] > items[j - 1][prop]) { //Swap the numbers var tmp = items[j]; items[j] = items[j - 1]; items[j - 1] = tmp; } } if(!reverse){ if (items[j][prop] < items[j - 1][prop]) { //Swap the numbers var tmp = items[j]; items[j] = items[j - 1]; items[j - 1] = tmp; } } } } return items; } 
  • the first argument items is the array of objects ,

  • prop is the key of the object on which you want to sort ,

  • reverse is a boolean parameter which on being true results in Ascending order and in false it returns descending order.

 // Sort Array of Objects // Data var booksArray = [ { first_nom: 'Lazslo', last_nom: 'Jamf' }, { first_nom: 'Pig', last_nom: 'Bodine' }, { first_nom: 'Pirate', last_nom: 'Prentice' } ]; // Property to Sort By var args = "last_nom"; // Function to Sort the Data by given Property function 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; }; } // Implementation var sortedArray = booksArray.sort(sortByProperty(args)); console.log("sortedArray: " + JSON.stringify(sortedArray) ); 

Console log output:

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

Adapted based on this source: http://www.levihackwith.com/code-snippet-how-to-sort-an-array-of-json-objects-by-property/

This will sort a two level nested array by the property passed to it in alpha numeric order.

 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')); 

I have a piece of code that works for me:

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