通过拆分哈希创建多个数组

时间:2016-11-22 21:11:07

标签: arrays ruby hash

假设我在哈希中有@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)。继续这样做,直到你有新哈希的所有免费号码......

1 个答案:

答案 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 

我想强调一点,我在第二个块变量中使用了下划线,强调它不用于块计算。