0

I have an array of currencies ["GBP", "EUR", "NOK", "DKK", "SKE", "USD", "SEK", "BGN"]. I would like to order it by moving predefined list if the currency is present to the beginning of array. Predefined list is ['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP']. So in this case it should return ['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP', 'SEK', BGN'].

But in case unfiltered array does not contain all values in predifined list it should also order it correctly. For example : ["GBP", "EUR", "NOK", "LTU", "ZGN"] should look like ['EUR', 'NOK', 'GBP', 'LTU', 'ZGN'

I was trying to sort it using this function:

list.sort(c => ['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP'].indexOf(c))

but it puts all predefined currencies at the end of the list, not at the from. Maybe there is a better way of doing that?

1
  • the callback for .sort() takes to arguments - the first and second comparator. you can do this same thing but with list.sort(( c, d ) => [...].indexOf(c) > [...].indexOf(d) ? 1 : [...].indexOf(c) < [...].indexOf(d) ? -1 : 0); but, adjust the > and < signs as needed. Commented Jun 7, 2016 at 6:12

4 Answers 4

2

You could use sorting with map and a hash table for the sort order. If the value is not in the hash table, the original order is taken.

var order = ['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP'],
    orderObj = Object.create(null),
    data = ["GBP", "EUR", "NOK", "DKK", "SKE", "USD", "SEK", "BGN"];

// generate hash table
order.forEach((a, i) => orderObj[a] = i + 1);

// temporary array holds objects with position and sort-value
var mapped = data.map((el, i) => { return { index: i, value: orderObj[el] || Infinity }; });

// sorting the mapped array containing the reduced values
mapped.sort((a, b) => a.value - b.value || a.index - b.index);

// assigning the resulting order
var data = mapped.map(el => data[el.index]);

console.log(data);

Sign up to request clarification or add additional context in comments.

3 Comments

Good answer. But since i'm using ES6 the last code part can be written in one line data .map((el, i) => { return { index: i, value: order[el] || 1000 }; }) .sort((a, b) => a.value - b.value || a.index - b.index) .map(el => d[el.index]);
Instead of 1000, better use the proper value Infinity :-)
@Bergi, great idea :-)
2

I guess this can also be achieved like this

Array.prototype.intersect = function(a) {
  return this.filter(e => a.includes(e));
};
Array.prototype.excludes = function(a) {
  return this.filter(e => !a.includes(e));
};
var getCur = (p,c) => p.intersect(c).concat(c.excludes(p)),
      cur1 = ["GBP", "EUR", "NOK", "DKK", "SKE", "USD", "SEK", "BGN"],
      cur2 = ["GBP", "EUR", "NOK", "LTU", "ZGN"],
       pdl = ['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP', 'SEK', 'BGN'];
console.log(getCur(pdl,cur1));
console.log(getCur(pdl,cur2));

1 Comment

Since you're using ES6 anyway, better go for a.includes(e)
0

var tabCurrency = ['GBP', 'EUR', 'NOK', 'DKK', 'SKE', 'USD', 'SEK', 'BGN'];

var tabPredef = ['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP'];

var newTabGood = [];

    tabPredef.forEach(function (itemPredef, indexPref) {

         var indexTemp;

         tabCurrency.forEach(function (itemCurrency, indexCurrency) {
               if(itemPredef == itemCurrency)
               {
                  newTabGood.push(itemPredef);
                  indexTemp = indexCurrency;
               }
         })

         tabCurrency.splice(indexTemp, 1)
   }) 


 var resultat = newTabGood.concat(tabCurrency);

 console.log(resultat)

Comments

0

here is my solution. :-)

//custom index of
Array.prototype.customIndexOf = function(a){
  return this.indexOf(a) === -1 ? Infinity : this.indexOf(a);
}

let orderArr = ['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP'];


/*test case 1*/
let urList = ["GBP", "EUR", "NOK", "DKK", "SKE", "USD", "SEK", "BGN"];
urList.sort((a, b) => { return orderArr.customIndexOf(a) - orderArr.customIndexOf(b); });
console.log(urList); //[ 'EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP', 'SEK', 'BGN' ]

/*test case 2*/
let newList = ["GBP", "EUR", "NOK", "LTU", "ZGN"];

newList.sort((a, b) => { return orderArr.customIndexOf(a) - orderArr.customIndexOf(b); });
console.log(newList); //[ 'EUR', 'NOK', 'GBP', 'LTU', 'ZGN' ]

hope this is what u need :-)

3 Comments

Why Number.MAX_VALUE? Just use Infinity.
anything.. we need one big value.. for comparison.. :)
But how big? Is 10000 enough? Is 2^31 enough? Better use the biggest value available - Infinity. Admittedly, as indexOf can't return anything larger than an array index, so anything above 2^32 will do, and Number.MAX_VALUE is way above that so it's fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.