按值排序对象

时间:2014-04-03 16:29:53

标签: javascript underscore.js

我在使用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"
}

我已经设法对它进行排序,但它用索引值替换了键。有任何想法吗?这应该是相当直接的。我错过了什么?

提前致谢!

3 个答案:

答案 0 :(得分:3)

您无法可靠地对JavaScript对象进行排序。 ES5 section 12.6.4说:

  

未指定枚举属性的机制和顺序(第一个算法中的步骤6.a,第二个算法中的步骤7.a)。

15.2.3.7节说:

  

如果实现为for-in语句定义了特定的枚举顺序,则必须使用相同的枚举顺序对此算法的步骤3中的列表元素进行排序。

Section 15.2.3.14Object.keys)说:

  

如果实现为for-in语句定义了特定的枚举顺序,则必须在此算法的步骤5中使用相同的枚举顺序。

您还可以查看8.6 The Object Type部分,了解是否有任何关于财产订单的提及(提示:没有)。所以在ES5中,属性顺序是依赖于实现的,唯一的限制是,或多或少,如果在任何地方都有定义的顺序,则该顺序必须在任何地方都相同。

ES6草案在section 9.1.11中包含类似的语言:

  

未指定枚举属性的机制和顺序,但必须符合下面指定的规则。

因此,对象中的内容绝对没有可移植且可靠的顺序。

不,你不能以JSON defines an object as

的形式通过JSON
  

......一组无序的名称/值对

有些JavaScript实现会按插入顺序对对象进行排序,但你不能依赖它。

您可以做的最好的事情是将您的Object转换为数组数组,如下所示:

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/

答案 1 :(得分:-1)

感谢“太短暂的答案”,它让我大部分时间。但是,它需要转换回一个对象,经过一些摆弄后,它非常简单。这是完整的答案:

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

var sortedDataObj = _.object( sortedDataArr );

答案 2 :(得分:-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"}"