How to sort an array of objects with array.Sort()

Asked

Viewed 41,788 times

13

Could I specify for the method array.sort(); What is the way of ordination? For example, I have an array of person objects, and person has name and number I wanted the sort to be done by name. How would I specify this for my Sort method?

  • The Sort method accepts a function, if you explain what you want to do (giving examples) we can help help this function

5 answers

25


The method sort accepts as parameter [optional] a function with two parameters - two objects to be compared by the sorting algorithm. This function must return a negative number if the first object is less than the second, a positive number if the second is less than the first, and zero if both are equal.

If you want to compare by the person’s name (which I assume is a string), a means is to compare these attributes and return the corresponding value:

pessoas.sort(function(a,b) {
    return a.nome < b.nome ? -1 : a.nome > b.nome ? 1 : 0;
});

12

The method .sort() accepts a function. This function will influence the final position through which that same function returns.

function compare(a, b) {
  if (se a fôr menor que b) {
    return -1;
  }
  if (a fôr maior que b) {
    return 1;
  }
  // são idênticos
  return 0;
}

That is, the function accepts two parameters to which elements of the array are assigned to be compared. If the function return greater than 0, then the element b shall "skip" the element a.

Example:

[0, 20, 3, 4].sort(function compare(a, b) {
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
})
// dá [0, 3, 4, 20]

If we compare the size of strings an example would be:

['muito longo', 'curto', 'médio'].sort(function compare(a, b) {
    if (a.length < b.length) return -1;
    if (a.length > b.length) return 1;
    return 0;
})
// dá ["curto", "médio", "muito longo"]

That is, if you find a feature to compare the elements of the array you have you can sort it by following this logic.

8

You can do it like this:

var pessoas = [ 
    { nome: 'Joao', num: 1     },
    { nome: 'Maria', num: 2     },
    { nome: 'Fulano', num: 3    }
    ];

function compare(a,b) {
  if (a.nome < b.nome)
     return -1;
  if (a.nome > b.nome)
    return 1;
  return 0;
}

pessoas.sort(compare);

If you want to sort by another attribute just modify the function compare.

Source

7

The simplest solution is to pass a function to the method sort array, manually comparing the properties of objects containing the names. The sort uses this function to compare pairs of values, and waits for it to return 0 for equal or equivalent strings, a positive number if the first value is greater than the second, or a negative number if the second is greater.

var pessoas = [{
    nome: "Mariana"
}, {
    nome: "Maria"
}, {
    nome: "Ana"
}];

pessoas.sort(function(a,b) {
    if(a.nome < b.nome) return -1;
    if(a.nome > b.nome) return 1;
    return 0;
});

But attention to the limitations of this method:

  • This method differentiates case from case ('A' < 'a'). This can be solved by converting everything to upper or lower case before comparing.
  • This method considers accented characters larger than the others (for example, 'Á' > 'z'). This can be solved replacing some characters before comparing.

A better solution to solve the accent problem, assuming that the browsers/operating systems of those running the script are set to English:

pessoas.sort(function(a,b) {
    return a.localeCompare(b);
});

Source: Reply of Rui Pimentel to How to order string array disregarding accents?.

That method localeCompare is available in any string, and also accepts a second argument that would be the string of locale you want to use (for example, "pt-BR"). But there are compatibility issues, according to MDN.

3

Summarizing with a little of each:

users = [
    {nome: "Thiago"},
    {nome: "thiago"},
    {nome: "Marcos"},
    {nome: "thiago"},
    {nome: "Ana"}
]

namesOrder(arrayObj){
    return arrayObj.sort(function(objA,objB) {
      a = aobjA.nome.toLowerCase().replace(/[àáâãäå]/,"a").replace(/[èéêë]/,"e").replace(/[ìíîï]/,"i").replace(/[òóôõö]/,"o").replace(/[ùúûü]/,"u").replace(/[ç]/,"c").replace(/[^a-z0-9]/gi,'')
      b = objB.nome.toLowerCase().replace(/[àáâãäå]/,"a").replace(/[èéêë]/,"e").replace(/[ìíîï]/,"i").replace(/[òóôõö]/,"o").replace(/[ùúûü]/,"u").replace(/[ç]/,"c").replace(/[^a-z0-9]/gi,'')
      return a < b ? -1 : a > b ? 1 : 0;
    })
  }

namesOrder(users)

It is worth noting that lowercase and replace will not be applied in the final object, only in the comparison object.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.