我有一段时间找到这个答案。
我想在JavaScript中使用哈希,如下所示:
const hash = {
a: 'A',
c: 'C',
b: 'B'
}
我希望通过 值 对对象进行排序,以便它可能变为:
const hash = {
a: 'A',
b: 'B',
c: 'C',
}
现在,我意识到POJSO不保证其密钥的顺序,所以我在考虑使用immutableJS
或一些保证哈希中密钥顺序的对象。
所以我正在寻找类似的东西:
var newHash = Immutable.Map(hash).sortBy(function(key,val){
return val;
});
但我不相信这存在。 这要问太多了吗?我怎样才能找到这个功能?
答案 0 :(得分:3)
现在,我意识到POJSO不保证其键的顺序
他们现在这样做,从ES2015开始。您仍然无法通过for-in
或Object.keys
访问该订单,但您可以通过Object.getOwnPropertyNames
访问该订单。订单由规范操作[[OwnPropertyKeys]]
给出。忽略继承的属性,它基本上是:作为整数索引的字符串的键,按数字顺序;其次是字符串的剩余键,按创建属性的顺序;其后是Symbol
个键,按照它们的创建顺序。
使用该信息,如果您的密钥都是不符合整数索引的字符串,那么在符合ES2015的引擎上,我们可以这样做:
以任何顺序开始使用属性(例如a
,c
,b
)
使用Object.keys
将这些密钥作为数组
使用Array#map
创建一个对象数组,其中包含键和值的属性(我在下面使用了k
和v
)
按值排序数组
使用Array#reduce
创建新对象,按排序顺序向其添加属性。 (有些人,包括我自己,可能会认为这是对reduce
的轻微误用,因为累加器实际上从未改变过,但是,嘿,它让我们全都变了[仍然是一件事吗?]并避免一个中间变量。嗯,因为这是一个目标?:-))
最终结果是一个对象,其属性按创建顺序排列,这是它们的值的顺序,因为我们按顺序创建它们。我们可以通过Object.getOwnPropertyNames
访问该订单。
// The unsorted data
let data = {
a: 'A',
c: 'C',
b: 'B'
};
// Create it sorted
const hash = Object.keys(data)
.map(key => ({k: key, v: data[key]}))
.sort((a, b) => a.v.localeCompare(b.v))
.reduce((o, e) => {
o[e.k] = e.v;
return o;
}, {});
// Display the sorted result
Object.getOwnPropertyNames(hash).forEach(n => {
snippet.log("hash['" + n + "'] = " + hash[n]);
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
除此之外,正如我在对这个问题的评论中所说,我不确定你为什么要这样做。看起来如果我们知道你的最终目标是什么,我们可能会指出你一个更有用的方向......
答案 1 :(得分:3)
Lodash单行:
sorted = _(hash).toPairs().sortBy(1).fromPairs().value();
直播示例:
var data = {a: 'A', c: 'C', b: 'B'};
var hash = _(data).toPairs().sortBy(1).fromPairs().value();
Object.getOwnPropertyNames(hash).forEach(n => {
snippet.log("hash['" + n + "'] = " + hash[n]);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>