Упорядочить массив по заранее определенным правилам

У меня есть массив валют["GBP", "EUR", "NOK", "DKK", "SKE", "USD", "SEK", "BGN"], Я хотел бы заказать его, переместив предварительно определенный список, если валюта присутствует в начале массива. Предопределенный список['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP'], Так что в этом случае он должен вернуться['EUR', 'USD', 'DKK', 'SKE', 'NOK', 'GBP', 'SEK', BGN'].

Но в случае, если нефильтрованный массив не содержит всех значений в предварительно определенном списке, он также должен правильно упорядочить его. Например :["GBP", "EUR", "NOK", "LTU", "ZGN"] должен выглядеть['EUR', 'NOK', 'GBP', 'LTU', 'ZGN'

Я пытался отсортировать его с помощью этой функции:

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

но все предопределенные валюты помещаются в конец списка, а не в from. Может быть, есть лучший способ сделать это?

 Deryck07 июн. 2016 г., 08:12
обратный вызов для.sort() принимает аргументы - первый и второй компаратор. Вы можете сделать то же самое, но сlist.sort(( c, d ) => [...].indexOf(c) > [...].indexOf(d) ? 1 : [...].indexOf(c) < [...].indexOf(d) ? -1 : 0); но, отрегулируйте> а также< знаки по мере необходимости.

Ответы на вопрос(4)

Решение Вопроса

сортировка по карте и хэш-таблица для порядка сортировки. Если значение отсутствует в хеш-таблице, принимается исходный порядок.

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

 Bergi07 июн. 2016 г., 17:16
Вместо1000лучше используйте правильное значениеInfinity :-)
 Nina Scholz07 июн. 2016 г., 08:43
@kuldarim, верно, не видел тега es6.
 kuldarim07 июн. 2016 г., 08:38
Хороший ответ. Но так как я использую ES6, последняя часть кода может быть записана в одну строку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]);
 Nina Scholz07 июн. 2016 г., 17:18
@ Берги, отличная идея :-)

//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' ]

надеюсь, это то, что тебе нужно :-)

 Brajendra Swain07 июн. 2016 г., 17:29
что-нибудь .. нам нужно одно большое значение .. для сравнения .. :)
 Brajendra Swain07 июн. 2016 г., 20:44
да .. поменял его на бесконечность :) спасибо
 Bergi07 июн. 2016 г., 17:17
ЗачемNumber.MAX_VALUE? Просто используйтеInfinity.
 Bergi07 июн. 2016 г., 17:33
Но насколько большой? Достаточно ли 10000? 2 ^ 31 достаточно? Лучше использовать наибольшую доступную стоимость -Infinity, По общему признанию, какindexOf не может вернуть ничего больше, чем индекс массива, так что все, что выше 2 ^ 32 будет делать, иNumber.MAX_VALUE это намного выше, так что все в порядке.

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

 Redu07 июн. 2016 г., 17:30
@ Берги круто ..! :)
 Bergi07 июн. 2016 г., 17:17
Так как вы используете ES6 в любом случае, лучше пойти наa.includes(e)
 Redu07 июн. 2016 г., 17:24
@ Берги Да, вы правы.

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)

Ваш ответ на вопрос