【问题标题】:How to return ordered key/value pairs from function?如何从函数返回有序的键/值对?
【发布时间】:2015-08-09 08:07:03
【问题描述】:

我有一个对象(哈希数组),我需要将它转换成有序的键值对。

这是对象:

var places_info = [
  {"place_id":180,"name":"Abc","city":"Gotham"},
  {"place_id":161,"name":"Def","city":"Sin City"},
  {"place_id":178,"name":"Ghi","city":"Timbuktu"},
  {"place_id":179,"name":"Jkl","city":"Acapulco"},
  {"place_id":174,"name":"Mno","city":"Desire"}
];

我需要函数以相同的顺序(按name 的字母顺序)返回键/值(place_id/name)对:

{ 
  '180': 'Abc', 
  '161': 'Def',
  '178': 'Ghi',
  '179': 'Jkl',
  '174': 'Mno'
}

实际使用:我需要它作为Jeditable Select-input 的输入(demo 页面上的实际示例)。 data-property 键/值对或返回它们的函数需要选择类型。到目前为止,我得到了随机顺序的选择选项,但是——正如你想象的那样——我需要它们按值排序....

至于 Jeditable,数据可能只是一个假哈希(字符串形式为 JSON 键/值对),我唯一的解决方案是这样的:

var arr = new Array;
for ( i in places_info ) {
  arr.push( "'" + places_info[i].place_id + "':'"  +  places_info[i].name + "'" );
}
var uglyString = '{' + arr.join(',') + '}';

是否有一些更优雅和直观的方法来实现这个目标?我想将我的数据保存在正确的数据结构中。将其转换为扁平字符串似乎是 hack。

编辑

我必须重新考虑这个问题。我没有使用生成的字符串测试 Jeditable,似乎它将字符串评估为哈希,然后我想要的订单就消失了。所以,这个问题需要不同的方法。也许我需要为 Jeditable 制作自己的数据类型。但这似乎是不同的问题。

【问题讨论】:

标签: javascript jeditable


【解决方案1】:

在 ES6 之前,Javascript 对象上的属性没有保证顺序。它们是无序的。如果您需要顺序并且需要支持 ES6 之前的环境,那么您不能只在对象上使用属性并获得这些属性的保证顺序。

所以你的选择是选择其他一些可以可靠地表达顺序的数据结构。像你所做的那样将它全部折叠成一个字符串是一种选择,尽管这意味着它必须重新解析才能对 Javascript 有用。最好将其保留为某种本机可访问的 Javascript 格式。对于订单,这意味着使用数组。


您可以通过返回一个用于排序的数组来返回有序对,然后有多种选择可以选择放入数组中的内容。下面是几个有序键/值对的例子:

// array of objects
var a = [{key: "greeting", value: "hello"}, {key: "salutation", value: "welcome"}];

因为这对我来说有点冗长,所以我经常使用一个快捷方式,它只知道每个其他元素都是一个键,然后是值,然后是键,然后是值,而不必一遍又一遍地拼出这些属性名称:

// alternating key/value
var a = ["greeting", "hello", "salutation", "welcome"];

或者,您可以将每个有序对放在一个数组本身中,这样每个子数组都是一个有序对:

// sub-arrays
var a = [["greeting", "hello"], ["salutation", "welcome"]];

【讨论】:

  • Jeditable 数据属性需要键/值对,我不能使用数组。
  • @w.k - 如果你想控制 Javascript 中的顺序,你可以使用数组。您不会轻易地操纵对象的属性顺序。事实上,在 ES6 之前,对象的属性没有保证的顺序。所以,因为你说你想要订单,所以我建议了一个数组——这就是 Javascript 用于订单的东西。如果可以使用字符串(yuk),那为什么不能使用数组呢?我不明白。我只是以为您正在尝试找到一种有组织的方式来存储有序的键/值对。
  • 我认为你是对的,因为即使使用字符串也不能像我预期的那样工作。请参阅我的编辑。谢谢!
【解决方案2】:

JavaScript 不保证对象中的属性顺序,需要使用数组。

看看这个:

var obj = {
   '180': 'Abc', 
   '161': 'Def',
   '178': 'Ghi',
   '179': 'Jkl',
   '174': 'Mno'
};
for (var i in obj) { console.log(i); };

会给你: 161、174、178、179、180

【讨论】:

    【解决方案3】:

    只需使用 JavaScript 的原生 Map 数据结构即可。它保持秩序。我们现在已经过了 2015 年,所以它应该是几乎所有运行时的标准。

    例如

    const m = new Map([["greeting", "hello"], ["salutation", "welcome"]])
    

    另见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 2017-08-10
      相关资源
      最近更新 更多