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

4095
我有一个JavaScript对象的数组:
var objs = [ 
    { first_nom: 'Laszlo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

如何在JavaScript中按last_nom的值对它们进行排序?
我知道sort(a,b),但似乎只适用于字符串和数字。我需要在我的对象中添加toString()方法吗?

2
大小写敏感或不敏感排序? - Peter Mortensen
61个回答

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

2

这里有一个函数可以用来按多个对象对列表进行排序,如果第一个对象相等,则使用第二个对象作为备选项。如果可能的话,也应该忽略空值以备选项排序。

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

1

我将为您提供一个实现选择排序算法的解决方案。它简单而有效。

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

1

尝试这种方式:

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

1
我会这样做:
[...objs].sort((a, b) => a.last_nom.localeCompare(b.last_nom))

1
如果您有嵌套的对象。
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"));

1
你还可以添加一个通用函数,用于对字符串和数字进行升序或降序排序,例如:

function sortArray({ data, key, sortingOrder }) {
    return data.sort((a, b) => {
      const firstValue = typeof a[key] === 'string' ? a[key]?.toLowerCase() : a[key];
      const secondValue = typeof b[key] === 'string' ? b[key]?.toLowerCase() : b[key];

      if (firstValue < secondValue) {
        return sortingOrder === SORT_ORDER.ASC ? -1 : 1;
      }
      if (firstValue > secondValue) {
        return sortingOrder === SORT_ORDER.ASC ? 1 : -1;
      }
      return 0;
    });
  }



const SORT_ORDER={
DES: 'Z-A',
ASC: 'A-Z'
};

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Zwalle'     },
    { first_nom: 'Pig',    last_nom: 'Podine'   },
    { first_nom: 'Pirate', last_nom: 'Antun' }
];

const sortedArray = sortArray({
data: objs,
key: 'last_nom',
sortingOrder: SORT_ORDER.ASC
});

console.log('sorted array', sortedArray);


1
  var objs = [ 
    { firstName: 'A', lastName: 'Mark'  }, // b
    { firstName: 'E', lastName: 'askavy' }, // a
    { firstName: 'C', lastName: 'peter' }
];

objs.sort((a,b) => {
   return a.firstName.localeCompare(b.firstName) // Sort Ascending 
}) 

objs.sort((a,b) => {
   return b.firstName.localeCompare(a.firstName) // Sort Decending
}) 

 console.log(objs)

0

我知道已经有很多答案,包括使用localeCompare的答案,但如果由于某些原因你不想/不能使用localeCompare,我建议你使用这个解决方案,而不是三元运算符的解决方案:

objects.sort((a, b) => (a.name > b.name) - (a.name < b.name));

有人可能会说,这段代码做了什么并不明显,但在我看来三元运算符更糟糕。如果一个三元运算符足够可读,两个三元运算符嵌套在一起——真的很难读,而且很丑。只有两个比较运算符和一个减号运算符的单行代码非常容易阅读,因此易于理解。

0

我是这样做的。

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

objs.sort(function(a, b) {
  const nameA = a.name.toUpperCase(); // ignore upper and lowercase
  const nameB = b.name.toUpperCase(); // ignore upper and lowercase
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }
  // names must be equal
  return 0;
});

console.log(arr);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接