最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Sorting array of custom objects in JavaScript - Stack Overflow

programmeradmin3浏览0评论

Say I have an array of Employee Objects:

var Employee = function(fname, age) {
    this.fname = fname;
    this.age = age;
}

var employees = [
    new Employee("Jack", "32"),
    new Employee("Dave", "31"),
    new Employee("Rick", "35"),
    new Employee("Anna", "33")
];


At this point, employees.sort() means nothing, because the interpreter does not know how to sort these custom objects. So I pass in my custom sort function.

employees.sort(function(employee1, employee2){
    return employee1.age > employee2.age;
});


Now employees.sort() works dandy.

But what if I also wanted to control what field to be sorted on, passing it in somehow during runtime? Can I do something like this?

employees.sort(function(employee1, employee2, on){
    if(on === 'age') {
        return employee1.age > employee2.age;
    }
    return employee1.fname > employee2.fname;
});

I can't get it to work, so suggestions? Design pattern based refactoring perhaps?

Say I have an array of Employee Objects:

var Employee = function(fname, age) {
    this.fname = fname;
    this.age = age;
}

var employees = [
    new Employee("Jack", "32"),
    new Employee("Dave", "31"),
    new Employee("Rick", "35"),
    new Employee("Anna", "33")
];


At this point, employees.sort() means nothing, because the interpreter does not know how to sort these custom objects. So I pass in my custom sort function.

employees.sort(function(employee1, employee2){
    return employee1.age > employee2.age;
});


Now employees.sort() works dandy.

But what if I also wanted to control what field to be sorted on, passing it in somehow during runtime? Can I do something like this?

employees.sort(function(employee1, employee2, on){
    if(on === 'age') {
        return employee1.age > employee2.age;
    }
    return employee1.fname > employee2.fname;
});

I can't get it to work, so suggestions? Design pattern based refactoring perhaps?

Share Improve this question asked May 23, 2012 at 16:05 user504674user504674
Add a comment  | 

3 Answers 3

Reset to default 15
function getSortFunction(fieldName) {
    return function(employee1, employee2) {
        return employee1[fieldName] > employee2[fieldName];
    }
}

employees.sort(getSortFunction("myField"));

Another solution is to use Function.prototype.bind if you are not afraid of it :)

function mySorter(fieldName, employee1, employee2) {
    return employee1[fieldName] > employee2[fieldName];
}

employees.sort(mySorter.bind(null, "myField"));

You could use the excellent library underscore.js' sortBy method.

For example:

var arr = [
    { name:"a", age:100 },  
    { name:"b", age:90 },
    { name:"c", age:80 },
    { name:"d", age:70 }
];

var sorted = _.sortBy(arr, "age");
console.log( sorted );

or in your case:

_.sortBy(employees, "age");

I provide my own sortBy method for arrays that lets you specify an arbitrary number of fields to sort by, using a Schwartzian transform:

Example 1

var a=[ {c:"GK",age:37}, {c:"ZK",age:13}, {c:"TK",age:14}, {c:"AK",age:13} ];

a.sortBy( function(){ return this.age } );                                   
// [ {c:"ZK",age:13}, {c:"AK",age:13}, {c:"TK",age:14}, {c:"GK",age:37} ] 

a.sortBy( function(){ return [this.age,this.c] } );                          
// [ {c:"AK",age:13}, {c:"ZK",age:13}, {c:"TK",age:14}, {c:"GK",age:37} ] 

a.sortBy( function(){ return -this.age } );                                  
// [ {c:"GK",age:37}, {c:"TK",age:14}, {c:"ZK",age:13}, {c:"AK",age:13} ] 

Example 2:

var n=[ 1, 99, 15, "2", "100", 3, 34, "foo", "bar" ];                        

n.sort();                                                                    
// [ 1, "100", 15, "2", 3, 34, 99, "bar", "foo" ]                         

n.sortBy( function(){ return this*1 } );                                     
// [ "foo", "bar", 1, "2", 3, 15, 34, 99, "100" ]                         

n.sortBy( function(o){ return [typeof o,this] } );                           
// [1, 3, 15, 34, 99, "100", "2", "bar", "foo"]                           

n.sortBy(function(o){ return [typeof o, typeof o=="string" ? o.length : o] })
// [1, 3, 15, 34, 99, "2", "100", "bar", "foo"]                           

The Code

(function(){
  // This code is copyright 2012 by Gavin Kistner, [email protected]
  // License: http://phrogz.net/JS/_ReuseLicense.txt
  if (typeof Object.defineProperty === 'function'){
    try{Object.defineProperty(Array.prototype,'sortBy',{value:sb}); }catch(e){}
  }
  if (!Array.prototype.sortBy) Array.prototype.sortBy = sb;

  function sb(f){
    for (var i=this.length;i;){
      var o = this[--i];
      this[i] = [].concat(f.call(o,o,i),o);
    }
    this.sort(function(a,b){
      for (var i=0,len=a.length;i<len;++i){
        if (a[i]!=b[i]) return a[i]<b[i]?-1:1;
      }
      return 0;
    });
    for (var i=this.length;i;){
      this[--i]=this[i][this[i].length-1];
    }
    return this;
  }
})();
发布评论

评论列表(0)

  1. 暂无评论