2016-11-22 5 views
0

@assortmentの数字がハッシュに含まれているとします。 1〜100です。 @assortmentの各番号は、:free、または:usedのステータスを持つことができます。ハッシュを分割して複数の配列を作成する

@assortmentは次のようになります。 {1 =>:無料、2 =>:無料、3 =>:使用等...}

は私がに基づいてアップ@assortmentを分割したいとしましょう数字を用い、それら自身ハッシュに無料番号を抽出する(またはアレイまたはハッシュ?)

例えば、1〜100の@assortmentために、数字25および75「が使用される」と残りがあった場合'free'の場合、結果はすべての空き値の3つの新しいハッシュになります。

1 to 24 
26 to 74 
76 to 100 

同様に、数字が1から100の異なるを持っていますが、数字20から80を抽出したいが、数字30,31,32および40を使用すると、結果は次のようになります。

hash1 -> 20 to 29 
hash2 ->33 to 39 
hash3 -> 41 to 80 

私は番号の完全な@assortmentに渡すことができルビー、でこれを行うための良い機能的な方法、そしておそらく配列で、抽出したハッシュを取得するためのオプションの範囲がありますか?

私はあなたがハッシュをループにした場合は、すべての空き番号が新しいハッシュ(例えばHASH1)に追加されます

...オリジナルのハッシュが:used要素に基づいて分割または分割ます推測あなたが使用された番号に達するまで。フリー・ナンバーに達するまでループを続けてください。これ以降のフリー・ナンバーはすべて新しいハッシュ(hash2)に追加されます。新しいハッシュのすべての自由な数字を持っているまで戻りに

+2

サンプルデータをRuby形式で追加できますか?あなたの質問から、入力と出力が何であるかははっきりと分かりません。あなたは '{1 =>:無料、2 =>:中古、...}'のようなものを意味しますか? – 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]あります。私はそれはブロックの計算に使用されていないことを強調するために、第2ブロック変数のためにアンダースコアを使用していたことを強調したい

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 

:3つのブロック変数が並列assignementを使用して計算されています。

+0

素晴らしいですね!これは、@assortmentがレール上のアクティブレコードの結果である場合にはかなり異なるでしょうか?配列の各要素が、number => "1"、:status = "free" ....私は、アクティブなレコードの結果をハッシュに変換すると思います。ここの例を参照してください。http://api.rubyonrails.org/classes/ActiveRecord/Result.html – user3437721

+0

だから、ハッシュの配列になると思いますハッシュよりも。それは繰り返しが必要でしょうか?またはおそらく平らになるかもしれない – user3437721

+0

私はRailsを知らないので、おそらく読者は最初の質問に答えることができます。私がハッシュの配列を返したら、ハッシュはどのように見えるでしょうか?すべての値は ':free'ですか? –

関連する問題