20

我有一个当前按名称排序的函数和一个值/键对数组。

我想知道如何传递正在执行哪种排序的键,以便每次都可以调用相同的函数,如下所示:

var arr = [{name:'bob', artist:'rudy'},
           {name:'johhny', artist:'drusko'},
           {name:'tiff', artist:'needell'},
           {name:'top', artist:'gear'}];

sort(arr, 'name');   //trying to sort by name
sort(arr, 'artist'); //trying to sort by artist

function sort(arr) {
  arr.sort(function(a, b) {
    var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase();
    if (nameA < nameB) //sort string ascending
      return -1;
    if (nameA > nameB)
      return 1;
    return 0; //default return value (no sorting)
   });          
}
4

5 回答 5

46
Array.prototype.sortOn = function(key){
    this.sort(function(a, b){
        if(a[key] < b[key]){
            return -1;
        }else if(a[key] > b[key]){
            return 1;
        }
        return 0;
    });
}



var arr = [{name:'bob', artist:'rudy'},{name:'johhny', artist:'drusko'},{name:'tiff', artist:'needell'},{name:'top', artist:'gear'}];

arr.sortOn("name");
arr.sortOn("artist");
于 2013-05-20T11:30:12.403 回答
20

[编辑 2020/08/14 ] 这是一个相当老的答案,也不是很好,所以简化和修改。

创建一个返回排序 lambda 的函数(Array.prototype.sort执行实际排序的回调)。该函数可以接收键名、排序类型(字符串(区分大小写或不区分大小写)或数字)和排序顺序(升序/降序)。lambda 使用参数值(闭包)来确定如何排序。

const log = (...strs) => 
  document.querySelector("pre").textContent += `\n${strs.join("\n")}`;
const showSortedValues = (arr, key) => 
  ` => ${arr.reduce((acc, val) => ([...acc, val[key]]), [])}`;
  
// the actual sort lamda factory function
const sortOnKey = (key, string, desc) => {
  const caseInsensitive = string && string === "CI";
  return (a, b) => {
    a = caseInsensitive ? a[key].toLowerCase() : a[key];
    b = caseInsensitive ? b[key].toLowerCase() : b[key];
    if (string) {
      return desc ? b.localeCompare(a) : a.localeCompare(b);
    }
    return desc ? b - a : a - b;
  }
};

// a few examples
const onNameStringAscendingCaseSensitive = 
  getTestArray().sort( sortOnKey("name", true) );
const onNameStringAscendingCaseInsensitive = 
  getTestArray().sort( sortOnKey("name", "CI", true) );
const onValueNumericDescending = 
  getTestArray().sort( sortOnKey("value", false, true) );

// examples
log(`*key = name, string ascending case sensitive`,
  showSortedValues(onNameStringAscendingCaseSensitive, "name")
);

log(`\n*key = name, string descending case insensitive`,
  showSortedValues(onNameStringAscendingCaseInsensitive, "name")
);

log(`\n*key = value, numeric desc`, 
  showSortedValues(onValueNumericDescending, "value")
);

function getTestArray() {
  return [{
    name: 'Bob',
    artist: 'Rudy',
    value: 23,
  }, {
    name: 'John',
    artist: 'Drusko',
    value: 123,
  }, {
    name: 'Tiff',
    artist: 'Needell',
    value: 1123,
  }, {
    name: 'Top',
    artist: 'Gear',
    value: 11123,
  }, {
    name: 'john',
    artist: 'Johanson',
    value: 12,
  }, ];
}
<pre></pre>

于 2013-05-20T12:01:18.910 回答
7
function keysrt(key) {
  return function(a,b){
   if (a[key] > b[key]) return 1;
   if (a[key] < b[key]) return -1;
   return 0;
  }
}

someArrayOfObjects.sort(keysrt('text'));
于 2014-11-10T17:41:35.807 回答
2

让您的生活变得轻松并使用闭包 https://stackoverflow.com/a/31846142/1001405

您可以在此处查看工作示例

var filter = 'name', //sort by name
data = [{name:'bob', artist:'rudy'},{name:'johhny', artist:'drusko'},{name:'tiff', artist:'needell'},{name:'top', artist:'gear'}];; 

var compare = function (filter) {
    return function (a,b) { //closure
        var a = a[filter],
            b = b[filter];

        if (a < b) {
            return -1;
        }else if (a > b) {
            return 1;
        } else {
            return 0;
        }
    };
};

filter = compare(filter); //set filter

console.log(data.sort(filter));
于 2015-08-06T03:08:51.877 回答
1

查看所有答案,我想出了自己的跨浏览器解决方案。接受的解决方案在 IE 或 Safari 中不起作用。此外,其他解决方案不允许按降序排序。

/*! FUNCTION: ARRAY.KEYSORT(); **/
Array.prototype.keySort = function(key, desc){
  this.sort(function(a, b) {
    var result = desc ? (a[key] < b[key]) : (a[key] > b[key]);
    return result ? 1 : -1;
  });
  return this;
}

var arr = [{name:'bob', artist:'rudy'}, {name:'johhny', artist:'drusko'}, {name:'tiff', artist:'needell'}, {name:'top', artist:'gear'}];
arr.keySort('artist');
arr.keySort('artist', true);
于 2015-07-01T14:15:28.700 回答