我有一个JavaScript对象数组:
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
如何在JavaScript中按last_nom的值对它们进行排序?
我知道排序(a,b),但这似乎只适用于字符串和数字。是否需要向对象添加toString()方法?
这是一个简单的问题。我不知道为什么人们会有如此复杂的解决方案。
一个简单的排序函数(基于快速排序算法):
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');
所以这里有一种排序算法,它可以在任何类型的对象数组中按任何顺序排序,而不受数据类型比较的限制(如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;
}
第一参数项是对象数组,prop是要排序的对象的键,reverse是一个布尔参数,如果为true,则返回升序,如果为false,则返回降序。
使用原型继承简单快速地解决此问题:
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"}]
更新:不再修改原始数组。
使用JavaScript排序方法
排序方法可以修改为使用比较函数对数字、字符串甚至对象数组进行排序。
比较函数作为可选参数传递给排序方法。
此比较函数接受两个参数,通常称为a和b。根据这两个参数可以修改排序方法,使其按需工作。
如果compare函数返回的值小于0,那么sort()方法将a排序到比b低的索引。如果compare函数返回的值等于0,那么sort()方法将保持元素位置不变。如果compare函数返回的值大于0,那么sort()方法会以大于b的索引对a进行排序。
使用上述概念应用于对象,其中a将是对象属性。
var对象=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'}];函数比较(a,b){如果(a.last_nom>b.last_nom)返回1;如果(a.last_nom<b.last_nom)返回-1;返回0;}objs.sort(比较);console.log(对象)//要获得更好的外观,请使用console.table(objs)
在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')) // OK
test.sort(sortByKey('id1')) // ERROR
test.sort(sortByKey('')) // ERROR