-1

My question is about fetching and sorting data (which includes accented words) before populating a "select" field on my application.

This is my code for fetching and populating a list of states (that are being sorted by their id's, and not by their names):

function populateUFs() {
  const ufSelect = document.querySelector("select[name=uf]")

  fetch("https://servicodados.ibge.gov.br/api/v1/localidades/estados")
    // .then( (res) => { return res.json() })
    .then(res => res.json())
    .then(states => {
      for (const state of states) {
        ufSelect.innerHTML += `<option value="${state.id}">${state.nome}</option>`
      }
    })
}

populateUFs()
<select name="uf">

</select>

How could I sort the list of states in alphabetic order, considering accented words please?

i.e.:

  • São Paulo
  • Santa Catarina
  • Tocantins

and not:

  • São Paulo
  • Amapá
  • Amazonas

Thanks.

2 Answers2

2

Use the Array.sort() method.

states.sort((a, b) => a.nome < b.nome ? -1 : a.nome === b.nome ? 0 : 1)

function populateUFs() {
  const ufSelect = document.querySelector("select[name=uf]")

  fetch("https://servicodados.ibge.gov.br/api/v1/localidades/estados")
    // .then( (res) => { return res.json() })
    .then(res => res.json())
    .then(states => {
      states.sort((a, b) => a.nome < b.nome ? -1 : a.nome === b.nome ? 0 : 1)
      for (const state of states) {
        ufSelect.innerHTML += `<option value="${state.id}">${state.nome}</option>`
      }
    })
}

populateUFs()
<select name="uf">

</select>

Array.sort() takes a sorting function that takes two elements of the array and returns a number which specifies which order they should be in.

  • if the number is positive sort the first element after the second element

  • if the number is negative sort the first element before the second element

  • if the number is zero don't change the order

(See this link for more information).

If you need your sort to work with accented characters use:

a.nome.localeCompare(b.nome) instead of a.nome < b.nome ? ...

Documentation for localeCompare()

anbcodes
  • 849
  • 6
  • 15
  • Awesome. It worked! Thanks a lot! I could use the Array.sort() function with states and also in cities populate() function. The only problem that came up was with cities that are accented (Álvares, for ex.), as they were placed to the end of the list (after Z). How could I fix that issue, placing those accented words after the non accented correspondent letter (Á after A; Ó after O). Thanks in advance. – Andre Peixoto Jun 20 '20 at 00:50
  • 1
    @AndrePeixoto I added an edit to hopefully fix your problem. – anbcodes Jun 21 '20 at 13:00
  • Thanks! That sorted out! – Andre Peixoto Jun 24 '20 at 17:31
1

You should use Array.sort

 states.sort((a, b) => (a.nome > b.nome) ? 1 : (b.nome > a.nome) ? -1 : 0)

and pass Compare function to it

The purpose of the compare function is to define an alternative sort order. The compare function should return a negative, zero, or positive value

If the result is negative a is sorted before b.

If the result is positive b is sorted before a.

If the result is 0 no changes are done with the sort order of the two values

const ufSelect = document.querySelector("#ufSelect")
fetch("https://servicodados.ibge.gov.br/api/v1/localidades/estados")
  // .then( (res) => { return res.json() })
  .then(res => res.json())
  .then(states => {
    states.sort((a, b) => (a.nome > b.nome) ? 1 : (b.nome > a.nome) ? -1 : 0)
    for (const state of states) {
      ufSelect.innerHTML += `<option value="${state.id}">${state.nome}</option>`
    }
  })
<select id="ufSelect"></select>
M A Salman
  • 3,666
  • 2
  • 12
  • 26
  • Awesome. It worked! Thanks a lot! I could use the Array.sort() function with states and also in cities populate() function. The only problem that came up was with cities that are accented (Álvares, for ex.), as they were placed to the end of the list (after Z). How could I fix that issue, placing those accented words after the non accented correspondent letter (Á after A; Ó after O). Thanks in advance. – Andre Peixoto Jun 20 '20 at 00:52