2015-09-04 32 views
0

我有以下JSON,如果類型是'水果'或'肉',我想根據'等級'進行重新排列。並保持JSON的其餘部分的顯示順序。 「水果」和「肉類」類型將具有排名,但類型「蔬菜」和「日記」排名不是強制性的,在某些情況下可能沒有。根據值重新排列JSON的一部分

原值:

var results = {"docs":[ 
    {"type":"fruit","name":"apple","rank": 10}, 
    {"type":"vegetable","name":"carrot","rank": 0}, 
    {"type":"fruit","name":"grape","rank": 9}, 
    {"type":"meat","name":"beef","rank": 9}, 
    {"type":"meat","name":"fish","rank": 10.1}, 
    {"type":"vegetable","name":"tamato"}, 
    {"type":"meat","name":"chicken","rank": 10}, 
    {"type":"diary","name":"eggs"}, 
    {"type":"vegetable","name":"peas","rank": 0}, 
    {"type":"fruit","name":"orange","rank": 9.1}, 
    {"type":"diary","name":"milk","rank": 10}, 
    {"type":"fruit","name":"banana","rank": 9.8} 
]}; 

期望值:

var results = {"docs":[ 
    {"type":"fruit","name":"apple","rank": 10}, 
    {"type":"fruit","name":"banana","rank": 9.8}, 
    {"type":"fruit","name":"orange","rank": 9.1}, 
    {"type":"fruit","name":"grape","rank": 9}, 
    {"type":"meat","name":"fish","rank": 10.1}, 
    {"type":"meat","name":"chicken","rank": 10}, 
    {"type":"meat","name":"beef","rank": 9}, 
    {"type":"vegetable","name":"carrot","rank": 0}, 
    {"type":"vegetable","name":"tamato"}, 
    {"type":"diary","name":"eggs"}, 
    {"type":"vegetable","name":"peas","rank": 0}, 
    {"type":"diary","name":"milk","rank": 10} 
]}; 

在此先感謝。感謝幫助。

回答

1

您的JSON對象的docs元素是一個JSON對象數組,因此您可以使用Array.sort()方法對JSON對象進行排序(請參閱:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)。訣竅是編寫一個排序函數,按您希望排序的方式排序您的JSON對象。

我這樣做是通過將其分解爲兩個函數,一個按類型排序,另一個按排名排序。

按類型排序時,我們希望將水果分類到比肉類低的指數,而乳製品和蔬菜分類到比水果或肉類低的指數。我們可以在compareType中使用類型數組的索引來幫助我們按類型進行排序。 「果實」的指數大於「肉」的指數,而不在數組中的任何指標(「乳製品」和「蔬菜」)的指數爲-1。類型數組中較低的索引對應於最終排序數組中較高的索引。因此,如果a.type < b.type,我們返回1.

當按排名排序時,應將較高排名排序爲較低排名索引。最後的排序函數首先比較對象的類型,如果類型相同,則比較它們的排名。

var results = {"docs":[ 
    {"type":"fruit","name":"apple","rank": 10}, 
    {"type":"vegetable","name":"carrot","rank": 0}, 
    {"type":"fruit","name":"grape","rank": 9}, 
    {"type":"meat","name":"beef","rank": 9}, 
    {"type":"meat","name":"fish","rank": 10.1}, 
    {"type":"vegetable","name":"tamato"}, 
    {"type":"meat","name":"chicken","rank": 10}, 
    {"type":"diary","name":"eggs"}, 
    {"type":"vegetable","name":"peas","rank": 0}, 
    {"type":"fruit","name":"orange","rank": 9.1}, 
    {"type":"diary","name":"milk","rank": 10}, 
    {"type":"fruit","name":"banana","rank": 9.8} 
]}; 

function compareRank(a, b) { 
    if(a.rank < b.rank) { 
    return 1; 
    } 
    else if(a.rank > b.rank) { 
    return -1; 
    } 
    else { 
    return 0; 
    } 
} 

function compareType(a, b) { 
    var types = ["meat", "fruit"]; 

    if(a.type === b.type) { 
    return 0; 
    } 
    else if(types.indexOf(a.type) < types.indexOf(b.type)) { 
    return 1; 
    } 
    else { 
    return -1; 
    } 
} 

var docs = results.docs; 
docs.sort(function(a, b) { 
    if(compareType(a, b) === 0) { 
    return compareRank(a, b); 
    } 
    else { 
    return compareType(a, b); 
    } 
}); 
+0

謝謝肖恩。完美的作品。 –

+0

我在IE和Chrome上獲得不同的結果?肉類和水果的排序很好,但有時在Chrome中,它並沒有保持其餘結果的順序。 –

+0

我的猜測是,不同的瀏覽器的JavaScript引擎以不同的方式實現排序算法。我們將蔬菜和乳製品等同對待,因此Chrome有時可能會重新分配蔬菜和乳製品。如果他們是平等的,他們的順序應該不重要。我知道你想保留蔬菜和奶製品的順序。我不知道你會怎麼做。也許你可以將它們從數組中移除,然後在對數組的其餘部分進行排序後將它們添加回去。 – Shawn

相關問題