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

时间:2009-07-15 03:17:47

标签: javascript arrays sorting

我有一个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()方法?

54 个答案:

答案 0 :(得分:3323)

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

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

答案 1 :(得分:746)

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

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

实际上这已经回答了这个问题。下面的部分是因为许多人与我联系,抱怨it doesn't work with multiple parameters

多个参数

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

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.apply(null, args));
    }
}

这样可以实现:

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

答案 2 :(得分:253)

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

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

答案 3 :(得分:174)

underscore.js

使用下划线,它的小而且很棒......

  

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

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

答案 4 :(得分:162)

不要理解为什么人们会这么复杂:

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

交换运算符,使其按反向字母顺序排序。

答案 5 :(得分:61)

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

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

答案 6 :(得分:42)

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

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

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

答案 7 :(得分:28)

您也可以使用自定义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();

答案 8 :(得分:26)

截至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 value
items.sort(function (a, b) {
  return a.value - b.value;
});

答案 9 :(得分:22)

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

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

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

想要逆转吗?没问题。使用_.reverse

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

想要使用Chaining来结合两者吗?

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

答案 10 :(得分:21)

您可以使用

最简单的方法: Lodash

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

此方法类似于_.sortBy,不同之处在于,它允许指定迭代对象的排序顺序。如果未指定订单,则所有值均按升序排序。否则,请为相应值的降序指定“ desc”的顺序或为升序指定“ asc”的顺序。

参数

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

返回

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


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

答案 11 :(得分:20)

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

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

fn1fn2,...是返回[-1,0,1]的排序函数。这导致按fn1&#34;排序,#34;按fn2&#34;排序。这几乎与SQL中的ORDER BY相同。

此解决方案基于||运算符的行为,该运算符的计算结果为first evaluated expression which can be converted to true

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

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

使用last_nomfirst_nom排序顺序执行两个步骤将如下所示:

// 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])

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

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

// 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可以在没有外部库或复杂代码的情况下走很长的路。它也非常有效,因为不需要进行字符串解析

答案 12 :(得分:19)

示例用法:

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

答案 13 :(得分:19)

尝试一下,

UPTO ES5

//Ascending Sort
items.sort(function (a, b) {
   return a.value - b.value;
});


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


IN ES6 & above:

// Ascending sort
items.sort((a, b) => a.value - b.value);

// Descending Sort
 items.sort((a, b) => b.value - a.value);

答案 14 :(得分:16)

我有一段适合我的代码:

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

更新:不能一直工作,所以不正确:(

答案 15 :(得分:16)

我还没有看到建议的这种特定方法,所以这是我喜欢使用的一种简洁的比较方法,该方法适用于stringnumber

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

const sortBy = fn => (a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) || +(fa > fb)
}
const getLastName = o => o.last_nom
const sortByLastName = sortBy(getLastName)

objs.sort(sortByLastName)
console.log(objs.map(getLastName))

以下是对sortBy()的解释:

sortBy()接受一个fn,该对象从对象中选择要用作比较的值,并返回可以直接传递给Array.prototype.sort()的函数。在此示例中,我们使用o.last_nom作为比较值,因此只要我们通过Array.prototype.sort()接收到两个对象,例如

{ first_nom: 'Lazslo', last_nom: 'Jamf' }

{ first_nom: 'Pig', last_nom: 'Bodine' }

我们使用

(a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) || +(fa > fb)
}

进行比较。

记住fn = o => o.last_nom,我们可以将比较功能扩展到等效功能

(a, b) => {
  const fa = a.last_nom
  const fb = b.last_nom
  return -(fa < fb) || +(fa > fb)
}

逻辑或||运算符具有短路功能,在这里非常有用。由于其工作方式,上面函数的主体意为

if (fa < fb) return -1
return +(fa > fb)

因此,如果fa < fb返回-1,否则返回fa > fb,但是如果返回+1,则返回fa == fb和{ {1}}是fa < fb,因此它返回fa > fb

作为一个额外的奖励,这是ECMAScript 5中没有箭头功能的等效项,不幸的是,它更加冗长:

false

答案 16 :(得分:15)

我知道这个问题太旧了,但我没有看到任何类似于我的实施 此版本基于Schwartzian transform idiom

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

答案 17 :(得分:14)

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

由于您可能会遇到更复杂的数据结构,例如此数组,我会扩展解决方案。

TL; DR

  

更可插拔的版本基于 @ege-Özcan 非常可爱answer

问题

我遇到了以下情况,无法改变它。我也不想暂时压扁物体。我也不想使用下划线/ 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.name排序,然后按People.Name.surname

排序

障碍

现在,在基础解决方案中使用括号表示法来计算要动态排序的属性。但是,在这里,我们还必须动态构造括号表示法,因为您会期望像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;
  }
}

实施例

工作示例on JSBin

答案 18 :(得分:11)

还有一个选择:

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

默认情况下按升序排序。

答案 19 :(得分:10)

一种简单的方法:

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

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

答案 20 :(得分:9)

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

用法:

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

答案 21 :(得分:9)

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

答案 22 :(得分:8)

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

答案 23 :(得分:8)

你为什么不写短代码?

objs.sort((a, b) => a.last_nom > b.last_nom && 1 || -1)

答案 24 :(得分:8)

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

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

试试这个例子at jsFiddle

答案 25 :(得分:8)

一个简单的函数,它通过属性

对对象数组进行排序
   <input type="password" name="password" placeholder="enter your password" 
`pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[$@#&!]).{6,12}"required>

用法:

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
}

答案 26 :(得分:7)

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

答案 27 :(得分:7)

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

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

})

答案 28 :(得分:7)

鉴于最初的例子:

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)universally supported,如果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;

答案 29 :(得分:6)

您可以使用可重用的排序功能。

Array.prototype.order= function(prop, methods = {}) {
  let swipe = 1;
  if (prop?.constructor == Object) methods = prop;
  swipe = methods.reverse ? -1 : 1;
  function key(x) {
    if (typeof prop == "string")
      return methods.insensitive ? String(x[prop]).toLowerCase() : x[prop];
    if (methods.insensitive) return String(x).toLowerCase();
    return x;
  }
  this.sort((a, b) => {
    if (key(a) < key(b)) return -1 * swipe;
    if (key(b) < key(a)) return 1 * swipe;
    return 0;
  });
  return this;
};

它可以用于对数组中的 Array Object 进行排序。

let arr = [6, 2, 4, 1, 5, 3];
let arr2 = [
  { name: "Bar", age: 12 },
  { name: "Nur", age: 18 },
  { name: "foo", age: 30 },
  { name: "bazz", age: 15 }
];
arr.order({ reverse: true }); //  [ 6, 5, 4, 3, 2, 1 ]
arr2.order("name", { reverse: 1, insensitive: 0});
let arr3 = [...arr2].order("age");  // new sorted array created from arr2 (But does not change original array)

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

答案 30 :(得分:6)

使用Ramda,

npm install 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)

答案 31 :(得分:6)

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

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

答案 32 :(得分:5)

我只是增强了Ege Özcan的动态排序来深入内部对象。 如果数据看起来像这样:

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.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

中的完整脚本

答案 33 :(得分:4)

区分大小写

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 将导致正确的输出

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

答案 34 :(得分:4)

使用 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"}
*/

答案 35 :(得分:4)

方式1:

您可以使用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);

答案 36 :(得分:3)

使用lodash或Underscore,它是一块蛋糕

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

答案 37 :(得分:3)

  

对我有用。在这里,它将未定义保留到最后。

 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 lowercase
        const value2 = b[property].toString().toUpperCase(); // ignore upper and lowercase
        if (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));
    
    

答案 38 :(得分:2)

我遇到了排序对象数组的问题,改变了值的优先级,基本上我想按照他们的年龄,然后通过姓氏 - 或仅仅通过姓氏,姓名来排列人们的数组。 我认为与其他答案相比,这是最简单的解决方案。

它'用于调用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>

答案 39 :(得分:2)

所以这里有一个排序算法,它可以在任何类型的对象的数组中以任何顺序排序,而不受数据类型比较的限制(即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;
}
  • 第一个参数 items 是对象数组,

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

  • reverse 是一个布尔参数,如果为true,则会产生升序,而在false中则返回降序。

答案 40 :(得分:2)

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

Compare 函数作为可选参数传递给 sort 方法。

Compare 函数接受 2 个参数,通常称为 ab。根据这 2 个参数,您可以修改 sort 方法以按需要工作。如果:

  1. 如果 compare 函数返回的值小于 0,则 sort() 方法以比 b 低的索引对 a 进行排序。只是 a 会出现在 b 之前。
  2. 如果 compare 函数返回等于 0,则 sort() 方法保持元素位置不变。
  3. 如果比较函数返回大于 0,则 sort() 方法在比 b 更大的索引处对 a 进行排序。 a 紧跟在 b 之后。

参考:Understanding sorting array of numbers, strings and objects

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

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)
enter image description here

答案 41 :(得分:2)

基于this出色的教程,我想开发Vlad Bezden answer并解释为什么localeCompare比诸如strA > strB之类的标准比较方法更好。让我们运行这个例子

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

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

进行编码

let str = '';

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

console.log(str);

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

如您所见,比较不同语言的字符并不是一件容易的事-但幸运的是,现代浏览器支持国际化标准ECMA-402。因此,在JS中,我们有strA.localeCompare(strB)做这项工作(-1表示strA小于strB; 1表示相反; 0表示相等)

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

我想补充一点,localeCompare支持两个参数:语言和附加的rules

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'

答案 42 :(得分:2)

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

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

答案 43 :(得分:2)

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

控制台日志输出:

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

根据此来源进行调整:http://www.levihackwith.com/code-snippet-how-to-sort-an-array-of-json-objects-by-property/

答案 44 :(得分:1)

这是我对此的看法:

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

function sortByProperty(array,property,order="ASC") {
  return array.sort((a,b) => order === "ASC" ?
    a[property] > b[property] ? 1 : a[property] < b[property] ? -1 : 0
  : a[property] > b[property] ? -1 : a[property] < b[property] ? 1 : 0
  );
}

SNIPPET

function sortByProperty(array,property,order="ASC") {
  return array.sort((a,b) => order === "ASC" ?
    a[property] > b[property] ? 1 : a[property] < b[property] ? -1 : 0
  : a[property] > b[property] ? -1 : a[property] < b[property] ? 1 : 0
  );
}

const rockStars = [
  { name: "Axl",
    lastname: "Rose" },
  { name: "Elthon",
    lastname: "John" },
  { name: "Paul",
    lastname: "McCartney" },
  { name: "Lou",
    lastname: "Reed" }
];

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

答案 45 :(得分:1)

此排序功能可用于所有对象排序

  • 对象

  • deepObject

  • 数字数组

您还可以通过将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 order
sording 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))

答案 46 :(得分:1)

简单答案:

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")); //-1
    console.log("aaa".localeCompare("aaa")); //0
    console.log("aab".localeCompare("aaa")); //1

    //example2:
    const a = 'réservé'; // with accents, lowercase
    const b = 'RESERVE'; // no accents, uppercase

    console.log(a.localeCompare(b));
    // expected output: 1
    console.log(a.localeCompare(b, 'en', { sensitivity: 'base' }));
    // expected output: 0

有关更多详细信息,请参见Mozilla文档localeCompare

答案 47 :(得分:1)

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

答案 48 :(得分:1)

我将为您提供一个实现selectionSort算法的解决方案,它简单有效

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 part
temp = 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);

很高兴看到这么棒的答案

答案 49 :(得分:0)

具有一个可用于按多个对象对列表进行排序的函数,如果第一个对象相等,则第二个顺序将用作后备。如果可能的话,空值也应忽略,以进行后备排序。

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

答案 50 :(得分:0)

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

答案 51 :(得分:0)

如果您有嵌套的对象

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 : -1
        return (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"));

答案 52 :(得分:0)

我一直在各种项目中使用此实用程序,并且效果很好。它也非常模块化:

  • 传递键名以进行排序
  • 选择是升序还是降序

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

答案 53 :(得分:0)

//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 comparison
        const 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));