2012-03-09 86 views
2

我想提出一個很好的方法來獲得如何在javascript中對數組進行排序的「建議」順序。按首選順序對數組進行排序

所以說,我的第一陣列看起來是這樣的:

['bob','david','steve','darrel','jim'] 

現在我所關心的,是排序結果順序開出:

['jim','steve','david'] 

在那之後,我想剩餘的值將按原始順序顯示。

所以我希望得到的結果是:

['jim','steve','david','bob','darrel'] 

我有我與通信的API,我想呈現的結果對我很重要在列表頂部。之後,我寧願他們只是按照原來的順序返回。

如果這可以很容易地用像jQuery這樣的javascript框架來完成,我也想聽聽。謝謝!

編輯爲清楚:

我想假設,我要排序的數組中提供的值都不能保證。

因此,在最初的例子,如果提供的是:

['bob','steve','darrel','jim'] 

而且我希望通過對它進行排序:

['jim','steve','david'] 

由於「大衛」是不提供的數組中,我我喜歡將結果排除在外。

EDIT2更加清晰: 的什麼,我試圖完成一個實際的例子:想與向用戶呈現我

['Load Average','Memory Usage','Disk Space'] 

的API將返回的東西看起來像首先是最重要的結果,但這些字段中的每一個可能並不總是被返回。所以我希望最重要的(如用戶在其他代碼中所確定的)在可用時首先顯示。

+0

是原來的靜態數組?或來自其他地方,可能是動態的? – 2012-03-09 03:55:46

+0

它來自一個API,所以它的值不能得到保證。即使我希望看到數組中的順序可能包含未提供的值。 – GoldenNewby 2012-03-09 03:57:58

+0

但是可以肯定的是,你需要開始的值總是'['jim','steve','david']'? – 2012-03-09 03:58:56

回答

2

像這樣的東西應該工作:

var presetOrder = ['jim','steve','david']; // needn't be hardcoded 

function sortSpecial(arr) { 
    var result = [], 
     i, j; 
    for (i = 0; i < presetOrder.length; i++) 
     while (-1 != (j = $.inArray(presetOrder[i], arr))) 
     result.push(arr.splice(j, 1)[0]); 
    return result.concat(arr); 
} 

var sorted = sortSpecial(['bob','david','steve','darrel','jim']); 

我允許出現比數組一次「特殊」的價值觀正在處理,並認爲應該重複,只要他們保持洗牌按照presetOrder中定義的順序排列在前面。

注意:我使用jQuery's $.inArray()而不是Array.indexOf(),只是因爲後者在IE9之前不被IE支持,並且已經用「jQuery」標記了您的問題。如果您不關心舊IE或使用shim,您當然可以使用.indexOf()

+0

這完全按照我的意願工作,我已經在我的代碼中實現了它。它的實際使用處理比我的例子明顯更復雜的情況。我會說,但我改變了接受一個「presetOrder」的功能。 – GoldenNewby 2012-03-09 04:26:26

+0

+1簡單! – PraveenLearnsEveryday 2012-03-09 10:43:53

0

您是否考慮過使用Underscore.js?它包含幾個用於處理這樣的列表的實用程序。

在你的情況,你可以:

  1. 過濾你想使用filter(),並將它們存儲在集合中的結果。

    var priorities = _.filter(['bob','david','steve','darrel','jim'], function(pName){ if (pName == 'jim' || pName == 'steve' || pName == 'david') return true; });

  2. 使用without()

    var leftovers = _.without(['bob','david','steve','darrel','jim'], 'jim', 'steve', 'david');

  3. 聯盟從前面的步驟陣列獲得其他結果的副本使用union()

    var finalList = _.union(priorities, leftovers);

0

http://tinysort.sjeiti.com/

我想這可能幫助。 $('#yrDiv').tsort({place:'start'});將在開始時添加您的重要列表。

您還可以按照自己喜歡的方式使用此功能進行排序。

0
var important_results = { 
    // object keys are the important results, values is their order 
    jim: 1, 
    steve: 2, 
    david: 3 
    }; 

// results is the orig array from the api 
results.sort(function(a,b) { 
    // If compareFunction(a, b) is less than 0, sort a to a lower index than b. 
    // See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort 
    var important_a = important_results[a], 
     important_b = important_results[b], 
     ret; 

    if (important_a && !important_b) {ret = -1} 
    else if (important_b && !important_a) {ret = 1} 
    else if (important_a && important_b) {ret = important_a - important_b} 
    else {ret = 0}; // keep original order if neither a or b is important 

    return(ret); 
    } 
) 

使用的是專門治療之前已知的重要結果的排序功能 - 它們排序的結果如果出現在結果的頭。在important_results

  • 項目不必在結果
0

這裏有一個簡單的測試頁:

<html> 
<head> 
<script language="javascript"> 
function test() 
{ 
    var items = ['bob', 'david', 'steve', 'darrel', 'jim']; 

    items.sort(function(a,b) 
     { 
      var map = {'jim':-3,'steve':-2,'david':-1}; 
      return map[a] - map[b]; 
     }); 
    alert(items.join(',')); 
} 
</script> 
</head> 
<body> 
<button onclick="javascript:test()">Click Me</button> 
</body> 
</html> 

它可以在大多數瀏覽器因爲JavaScript 通常採用的是稱爲stable sort algorithm,其定義特徵是它保留原始訂單等效項目。但是,我知道有例外。通過使用每個剩餘項目的數組索引來保證穩定性,因爲它是a1/b1值。

+0

我喜歡你的答案的預編輯版本,但我不確定我是否理解新版本:你提到在a1/b1值中使用item index,但是如何從'.sort )'回調? (你現在是不是在很多情況下返回'NaN'? – nnnnnn 2012-03-09 04:47:16

+0

@nnnnnn它現在不會返回NaN:它將是'undefined',並且javascript保證'undefined'將被視爲'0'用於減法操作。另一方面,由於我們無法保證將使用哪種算法,這意味着在排序之前添加代碼以搜索數組並設置每個項目在地圖中的位置。 – 2012-03-09 04:51:59

+0

我不是說它不會在你的函數的上下文中工作,但不'undefined - undefined'返回'NaN'? (它絕對在IE中,我只是試了一下。) – nnnnnn 2012-03-09 05:15:28

0

現場演示(的jsfiddle似乎是向下)

http://jsbin.com/eteniz/edit#javascript,html

var priorities=['jim','steve','david']; 

var liveData=['bob','david','steve','darrel','jim']; 


var output=[],temp=[]; 
for (i=0; i<liveData.length; i++){ 
    if($.inArray(liveData[i], priorities) ==-1){ 
     output.push(liveData[i]); 
    }else{ 
     temp.push(liveData[i]); 
    } 
} 
var temp2=$.grep(priorities, function(name,i){ 
     return $.inArray(name, temp) >-1;        
}); 

output=$.merge(temp2, output); 
相關問題