2016-06-07 58 views
0

我有一系列貨幣["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)) 

但是卻讓所有預定義的貨幣在列表的末尾,而不是在從。也許有更好的方法來做到這一點?

+0

'.sort()'的回調需要參數 - 第一個和第二個比較器。你可以用'list.sort((c,d)=> [...]。indexOf(c)> [...]。indexOf(d)?1:[...]來做同樣的事情。 indexOf(c)<[...]。indexOf(d)?-1:0);'但是,根據需要調整'>'和'<? – Deryck

回答

2

您可以使用sorting with map和散列表作爲排序順序。如果該值不在散列表中,則採用原始順序。

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

+0

很好的答案。但是由於我使用的是ES6,所以最後的代碼部分可以寫成一行'data .map((el,i)=> {return {index:i,value:order [el] || 1000};}) ((a,b)=> a.value-b.value || a.index -b.index) .map(el => d [el.index]);' – kuldarim

+0

@ kuldarim,right,沒有看到es6標籤。 –

+1

而不是'1000',最好使用適當的值'Infinity' :-) – Bergi

2

我想這也可以這樣

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

既然你用的是ES6,最好去'a.includes(e)' – Bergi

+0

@Bergi你是對的。 – Redu

+0

@Bergi很酷..! :) – Redu

0

這裏是我的解決方案來實現的。 :-)

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

希望這是什麼ü需要:-)

+0

爲什麼'Number.MAX_VALUE'?只需使用'Infinity'。 – Bergi

+0

什麼..我們需要一個大的價值..比較.. :) –

+0

但有多大? 10000夠了嗎? 2^31夠了嗎?更好地利用可用的最大價值 - 「無限」。無可否認,由於'indexOf'不能返回大於數組索引的任何東西,因此大於2^32的任何值都會執行,而'Number。MAX_VALUE'遠高於此值,所以沒問題。 – Bergi

0

VAR tabCurrency = [ '英鎊', '歐元', '諾', '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)