2014-04-03 135 views
1

我在使用Underscore時遇到了困難。我想按字母順序排列下面的對象的值,並以相同的格式返回它。按值排序對象

{ 
    "accommodation" : "Accommodation", 
    "bed-breakfast" : "Bed & Breakfast", 
    "caravan-camping" : "Caravan & Camping", 
    "cottages" : "Cottages", 
    "friends-family" : "Friends & Family", 
    "health-spas" : "Health Spas", 
    "hostels" : "Hostels", 
    "hotels" : "Hotels", 
    "self-catering" : "Self Catering", 
    "backpacking" : "Backpacking", 
    "car-touring" : "Car Touring" 
} 

我設法對它進行排序,但它用索引值替換了鍵。有任何想法嗎?這應該是相當直接的。我錯過了什麼?

在此先感謝!

+5

JS對象沒有順序。您無法以編程方式對對象進行排序。只有數組。 – Andy

+0

我只是想說,安迪:D –

+0

我強烈建議**不要**存儲HTML轉義的文本。在HTML上下文中使用它時,應將其轉換爲HTML。否則,你很早就混淆了你的數據方式,並且不能將它用於其他目的。 – Brad

回答

-1

感謝'畝太短的答案,它讓我大部分的方式。但是,它需要轉換回一個對象,經過一些擺弄之後,它非常簡單。下面是完整的答案:

var sortedDataArr = _(data).chain() 
          .pairs() 
          .sortBy(_.last) 
          .value(); 

var sortedDataObj = _.object(sortedDataArr); 
+0

正如我上面所說的,這不能保證工作,因爲在對象中沒有指定的順序。如果您需要按照特定順序進行操作,則會使用錯誤的數據結構。 –

-3

JS對象沒有順序。您無法以編程方式對對象進行排序。只有陣列

不是真的。當您在對象上調用JSON.stringify時,輸出字符串中屬性的順序是在該對象上定義屬性的順序。這同樣適用於Object.keys(obj)for(var property in obj)(假設obj是您的對象)。你可以這樣做:

var originalObject = { 
    "accommodation" : "Accommodation", 
    "bed-breakfast" : "Bed & Breakfast", 
    "caravan-camping" : "Caravan & Camping", 
    "cottages" : "Cottages", 
    "friends-family" : "Friends & Family", 
    "health-spas" : "Health Spas", 
    "hostels" : "Hostels", 
    "hotels" : "Hotels", 
    "self-catering" : "Self Catering", 
    "backpacking" : "Backpacking", 
    "car-touring" : "Car Touring" 
}; 
// map your object onto an array [key, value] 
var arr = _.map(originalObject, function(value, key) { 
    return [key, value]; 
}); 
// sort it by originalObject's values 
arr.sort(function(a, b) { 
    return a[1].localeCompare(b[1]); 
}); 
// create an object from an array 
var obj = _.object(arr); 

JSON.stringify(originalObject)產量:

"{"accommodation":"Accommodation","bed-breakfast":"Bed & Breakfast","caravan-camping":"Caravan & Camping","cottages":"Cottages","friends-family":"Friends & Family","health-spas":"Health Spas","hostels":"Hostels","hotels":"Hotels","self-catering":"Self Catering","backpacking":"Backpacking","car-touring":"Car Touring"}" 

JSON.stringify(obj)產量:

"{"accommodation":"Accommodation","backpacking":"Backpacking","bed-breakfast":"Bed & Breakfast","car-touring":"Car Touring","caravan-camping":"Caravan & Camping","cottages":"Cottages","friends-family":"Friends & Family","health-spas":"Health Spas","hostels":"Hostels","hotels":"Hotels","self-catering":"Self Catering"}" 
+1

你有備份你的訂單斷言的參考嗎? –

3

不能可靠地排序JavaScript對象。 ES5 section 12.6.4說:

的力學和列舉的屬性順序(步驟6.A在第一算法,在第二步驟7.A)沒有被指定。

15.2.3.7說:

如果實現定義枚舉的特定順序對換的說法,同樣的枚舉順序,必須使用命令在該算法的步驟3中的列表元素。

Section 15.2.3.14Object.keys)表示:

如果一個實現定義枚舉的特定順序對換在聲明,相同的枚舉順序必須在該算法的步驟5中使用。

你也可以看8.6 The Object Type看看是否有任何提及屬性順序(提示:沒有)。因此,在ES5中,屬性順序依賴於實現,唯一的限制或多或少是,如果在任何地方都有定義的順序,則該順序必須在任何地方都一樣。

的ES6草案中包含類似的語言在section 9.1.11

機制和枚舉未指定屬性的順序,但必須符合以下指定的規則。

所以在對象中絕對沒有可移植和可靠的順序。

沒有,則無法通過JSON無論是作爲JSON defines an object as去:

...一個無序的名稱/值對

一些JavaScript實現訂貨會按廣告訂單對象但你不能依賴這一點。

你可以做的是你的對象轉換爲陣列的陣列像這樣的東西最好的:

var sorted = _(obj).chain() 
        .pairs() 
        .sortBy(_.last) 
        .value(); 

或數組對象的-:

var sorted2 = _(obj).chain() 
        .pairs() 
        .sortBy(_.last) 
        .map(function(a) { return _([a]).object() }) 
        .value(); 

演示:http://jsfiddle.net/ambiguous/76ZPx/

+0

非常感謝非常詳細的答案。然而,這隻會返回一堆數組,因爲我需要一個格式相同的對象。它已經讓我99%的方式,雖然:) – DanV

+0

對象沒有明確定義的順序。除非你想從瀏覽器(現在和將來的版本)中採取非標準的行爲,否則你所要求的是不可能的。 –