2013-07-15 112 views
0

我有看起来像这样的秩序轨的哈希

{"1-5 lbs"=>107342.43999999999, "31+ lbs"=>39838.58000000001, "21-30 lbs"=>19036.41, "11-20 lbs"=>39350.95, "6-10 lbs"=>41401.880000000005}

而且我想,所以它看起来像这样

{"1-5 lbs"=>107342.43999999999, "6-10 lbs"=>41401.880000000005, "11-20 lbs"=>39350.95, "21-30 lbs"=>19036.41, "31+ lbs"=>39838.58000000001 }

的对它进行排序的散列逻辑被存储在一个实例变量中@weight_ranges

回答

2

您需要进入正则表达式才能获取值e的每个 范围的第一个数字。

Hash[(@weight_ranges.sort_by {|key, value| key.scan(/\d+/)[0].to_i})] 

为了进一步打破它:

# Sort the weight ranges by the first series of digits found in the key 
x = @weight_ranges.sort_by {|key, value| key.scan(/\d+/)[0].to_i} 
# Convert each inner Array to a key, value pair in a Hash 
x = Hash[x] 
+0

其实你可以在这里没有正则表达式。 – Gene

+0

好点 - 关于'#to_i'工作方式的提示。 – acsmith

1

您所描述的数据作为哈希值。对于一个序列,你需要一对数组。像这样的东西会做:

list_of_pairs = @weight_ranges.keys.sort_by(&:to_i).map {|k| [k, @weight_ranges[k]]} 

这利用了一个令人高兴的巧合to_i停在第一个非数字它看到。

修正

我刚刚了解到,在1.9 Ruby的哈希值进行排序!所以很容易适应:

Hash[@weight_ranges.sort_by{|k,v| k.to_i}] 

我会离开这里既想法,因为第一个是正确的仍然为Ruby < 1.9。

+0

一注 - 第一个例子实际上返回一个数组,而不是一个哈希,我认为他正在寻找。但是将其封装在Hash []中解决了这一问题。 – acsmith

+0

@acsmith对。直到有人发布Ruby哈希现在已经订购,我才意识到。在1.9之前他们没有。所以我认为他需要数组来获得严格的序列。我不确定哪种方法可以创造更少的垃圾。 “merge!”仍然需要一个1键哈希来表示它的参数。大概应该尝试简单的任务。 – Gene