'Sorting arrays in JavaScript [closed]

I received a big array of object from the backend and I used filtering to leave only these values

const markets = ['IT', 'DE', 'UK', 'FR', 'NL', 'US'] // so now this is what have

I am going then to map through markets, but it will always start by IT and follows that order. Is there a way to sort this following a specific order?

['US', 'DE', 'UK', 'FR', 'IT', 'NL']

I want to sort every array that i receive following this specific order even if I don't receive all the values.



Solution 1:[1]

You can assign each market a value within an object, and use that to compare and sort against the market array you receive from the backend:

const markets = ['IT', 'DE', 'UK', 'FR', 'NL', 'US']

let mappedMarkets = {
  'US': 1,
  'DE': 2,
  'UK': 3,
  'FR': 4,
  'IT': 5,
  'NL': 6
}

console.log(markets.sort((a, b) => mappedMarkets[a] - mappedMarkets[b]))

Solution 2:[2]

One could implement a function which uses an object as lookup for each of a market's precedence value and which in addition places unknown market items last.

function getAssuredMarketPrecedence(marketList) {
  const marketPrecedence = {
    US: 0, DE: 1, UK: 2, FR: 3, IT: 4, NL: 5,
  };
  return Array
    .from(marketList)
    .sort((a, b) =>
      (marketPrecedence[a] ?? 1000)  - (marketPrecedence[b] ?? 1000)
    );
}
const markets = ['IT', 'DE', 'unknown2', 'UK', 'FR', 'unknown1', 'NL', 'US']
const sorted = getAssuredMarketPrecedence(markets);

console.log({ markets, sorted });
.as-console-wrapper { min-height: 100%!important; top: 0; }

Solution 3:[3]

You need to write your own custom compare function

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Smth like this:

markets = ['IT', 'DE', 'UK', 'FR', 'NL', 'US']

markets.sort((item1, item2) => {
    neededOrder = ['US', 'DE', 'UK', 'FR', 'IT', 'NL']
    idx1 = neededOrder.indexOf(item1)
    idx2 = neededOrder.indexOf(item2)
    if(idx1 < idx2) {
        return -1
    }
    else if(idx1 > idx2) {
        return 1
    } else {
        return 0
    }
})

Solution 4:[4]

You can:

  • Break the list into two sub-arrays
  • Those on the order list which you can sort in the desired order
  • Those not on the list which you do not have to sort
  • Combine the sub-arrays using: [...s1, ...s2]

const markets = ['IT', 'DE', 'UK', 'FR', 'NL', 'US','KE','UG','TZ'], // so now this is what have
      order = ['US', 'DE', 'UK', 'FR', 'IT', 'NL'],
      
      output = [
          ...markets.filter(c => order.includes(c)).sort(
              (a, b) =>
              order.findIndex(x => x === a) - order.findIndex(x => x === b)
          ),
          ...markets.filter(c => !order.includes(c))
      ];
      
      
console.log( output );

Alternatively, ...

If each markets only includes items that are in order you can just leave out the second sub-array and use the following instead:

const markets = ['IT', 'DE', 'UK', 'NL', 'US'], 
      order = ['US', 'DE', 'UK', 'FR', 'IT', 'NL'],
      
      output = markets.filter(c => order.includes(c)).sort(
          (a, b) =>
          order.findIndex(x => x === a) - order.findIndex(x => x === b)
      );
      
      
console.log( output );

Solution 5:[5]

I am afraid there is no such way, it should be ascending or descending. Or if it is not that much data, you can sort that manually.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Marco
Solution 2
Solution 3
Solution 4
Solution 5 Alazar-dev