2016-11-22 41 views
0

可以说我有一个散列中的数字@assortment,例如, 1至100. @assortment中的每个号码可以具有:free:used的状态。通过分割散列创建多个阵列

一个例子@assortment可以是: {1 =>:免费,2 =>:免费,3 =>:使用等...}

可以说,我想基于所述最多分裂@assortment使用的数字,并提取游离号码到他们自己散列(或阵列或哈希?)

例如,对于为1的@assortment到100中,如果数字25和75分别“使用”和其余均'free',那么结果将是所有自由值的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)中。保持此下去,直到你把所有的免费电话号码在新的哈希...

+2

您可以添加一些Ruby格式的示例数据吗?从你的问题来看,不清楚输入和输出是什么。你的意思是像'{1 =>:free,2 =>:used,...}'? – tadman

+0

是的,假设它是这种格式,我会加上 – user3437721

+0

这个问题,并且添加预期的输出格式,它有很大的帮助。 – tadman

回答

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]。三个块变量使用平行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 

我想强调的是,我使用下划线用于第二块变量强调,它未在块计算中使用。

+0

看起来不错!如果@assortment在rails中是一个活动记录结果,这会有很大的不同,所以我认为这是一个数组,其中的每个元素都是属性的哈希值:number =>“1”,:status =>“free” ....我想我将活动记录结果转换为哈希,请参阅http://api.rubyonrails.org/classes/ActiveRecord/Result.html – user3437721

+0

中的示例所以我想这应该是一个哈希数组,比散列。这需要迭代吗?或者它可能会变平坦 – user3437721

+0

我不知道Rails,所以也许读者可以回答第一个问题。如果我返回了一列哈希值,哈希值是什么样的?所有的值都是':free'吗? –