1.9 之前的 Ruby 没有维护哈希的“插入”顺序。这是一种强制已知顺序的方法,而不依赖于排序:
BASE_COST = 2.0
COST_OF_GROCERIES = {
"milk" => 3.50,
"egg" => 1.50,
"broccolli" => 0.75
}
DESIRED_ORDER = %w[milk egg broccolli]
COST_OF_GROCERIES.values_at(*DESIRED_ORDER) # => [3.5, 1.5, 0.75]
这仅以所需的顺序返回值。
以下是按相同顺序处理哈希的方法:
DESIRED_ORDER.each do |k|
lt_gt = COST_OF_GROCERIES[k] > BASE_COST ? 'more' : 'less'
puts '%s is %s than %0.2f' % [k, lt_gt, BASE_COST]
end
# >> milk is more than 2.00
# >> egg is less than 2.00
# >> broccolli is less than 2.00
这是另一种看待它的方式......
Enumerablezip
让我们连接两个数组的元素,将它们交织在一起:
DESIRED_ORDER.zip(COST_OF_GROCERIES.values_at(*DESIRED_ORDER)) # => [["milk", 3.5], ["egg", 1.5], ["broccolli", 0.75]]
我们可以将输出 from 传递给以zip
添加map
价格是“更多”还是“更少”:
groceries = DESIRED_ORDER.zip(COST_OF_GROCERIES.values_at(*DESIRED_ORDER)).map{ |grocery, price|
[
grocery,
price,
price > BASE_COST ? 'more' : 'less'
]
}
groceries # => [["milk", 3.5, "more"], ["egg", 1.5, "less"], ["broccolli", 0.75, "less"]]
查看以下内容groceries
:如果您使用 ERB 或 Haml 渲染网页,数组中的数组正是您想要传递给视图的那种数据。
然后我们可以生成一些输出字符串并打印出来:
puts groceries.map{ |ary|
'%s, at $%.2f is %s than $%0.2f' % [*ary, BASE_COST]
}
# >> milk, at $3.50 is more than $2.00
# >> egg, at $1.50 is less than $2.00
# >> broccolli, at $0.75 is less than $2.00
使用格式字符串类似于 ERB 或 Haml 模板。这距离 ERB/Haml 的起步仅几步之遥。
我把上面的步骤分解成更小的步骤,但实际的过程可以写成:
puts DESIRED_ORDER.zip(COST_OF_GROCERIES.values_at(*DESIRED_ORDER)).map{ |grocery, price|
[
grocery,
price,
price > BASE_COST ? 'more' : 'less'
]
}.map{ |ary|
'%s, at $%.2f is %s than $%0.2f' % [*ary, BASE_COST]
}
# >> milk, at $3.50 is more than $2.00
# >> egg, at $1.50 is less than $2.00
# >> broccolli, at $0.75 is less than $2.00