假设我在哈希中有@assortment
个数字,例如1到100。
@assortment
中的每个号码的状态均为:free
或:used
。
示例@assortment
可以是:
{1 => :免费,2 => :免费,3 => :使用等...}
假设我想根据使用的数字拆分@assortment
,并将免费数字提取到他们的自己的哈希(或数组或哈希?)
例如,对于1到100的@assortment
,如果使用数字25和75,则使用'其余的是免费的,然后结果将是所有自由值的3个新哈希:
1 to 24
26 to 74
76 to 100
同样地,假设我们有一个不同的@assortmen
t,数字1到100,但我想提取数字20到80,但是使用数字30,31,32和40然后结果就像这个:
hash1 -> 20 to 29
hash2 ->33 to 39
hash3 -> 41 to 80
在Ruby中有没有一个很好的功能方法,我可以在其中传递完整的@assortment
数字,以及一个可选范围来提取和获取结果哈希值,可能是在数组中?
我猜原始哈希会根据:used
元素分解或拆分...
如果你要遍历哈希值,那么每个空闲号码都会被添加到一个新的哈希值(例如hash1),直到你找到一个用过的号码。继续循环直到你到达一个空闲号码,这个和所有后续的免费号码被添加到一个新的哈希值(hash2)。继续这样做,直到你有新哈希的所有免费号码......
答案 0 :(得分:2)
@assortment = (20..50).to_a.product([:free]).to_h
[30,31,32,40].each { |n| @assortment[n] = :used }
@assortment
# => {20=>:free, 21=>:free, 22=>:free, 23=>:free, 24=>:free, 25=>:free,
# 26=>:free, 27=>:free, 28=>:free, 29=>:free, 30=>:used, 31=>:used,
# 32=>:used, 33=>:free, 34=>:free, 35=>:free, 36=>:free, 37=>:free,
# 38=>:free, 39=>:free, 40=>:used, 41=>:free, 42=>:free, 43=>:free,
# 44=>:free, 45=>:free, 46=>:free, 47=>:free, 48=>:free, 49=>:free, 50=>:free}
返回一系列哈希
@assortment.reject { |_,v| v == :used }.
slice_when { |(a,_),(b,_)| b > a+1 }.
to_a.
map(&:to_h)
#=> [{20=>:free, 21=>:free,...29=>:free},
# {33=>:free, 34=>:free,...39=>:free},
# {41=>:free, 42=>:free,...50=>:free}]
请参阅Hash#reject(返回哈希值)和Enumerable#slice_when。
返回数组数组
拥有一个值非常相似的哈希并不是很有用。如果您更喜欢返回一个数组数组,只需删除to_h
。
arr = @assortment.reject { |_,v| v == :used }.
keys.
slice_when { |a,b| b > a+1 }.
to_a
#=> [[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
# [33, 34, 35, 36, 37, 38, 39],
# [41, 42, 43, 44, 45, 46, 47, 48, 49, 50]]
返回范围数组
第三种选择是返回范围数组。为此,将arr
个元素(数组)中的每一个映射到范围:
arr.map { |f,*_,l| f..l }
#=> [20..29, 33..39, 41..50]
传递给块的arr
的第一个元素是[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
。使用 parallel assignement 计算三个块变量:
f,*b,l = [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
f #=> 20
_ #=> [21, 22, 23, 24, 25, 26, 27, 28]
l #=> 29
我想强调一点,我在第二个块变量中使用了下划线,强调它不用于块计算。