2017-05-31 21 views
-4

私はそのような配列を持っています。望ましい出力を得るのを助けてください。配列操作とルビーの計算

arr = [["IT", "Testing"], ["IT", "Banking Software"], ["IT", "ERP"], 
     ["IT", "Testing"], ["IT", "IT Security"], ["IT", "ERP"], 
     ["IT", "IT Security"], ["Accounting", "Offshore"], ["IT", "Testing"], 
     ["Accounting", "ACCA"]] 

私はarrから(単一のハッシュを含む)は、以下の配列を構築したい:

.MAP、.group_by、まだありません成功を収めてみました
[ 
{ 
    "IT" => [["Testing", 3], ["ERP", 2], ["IT Security", 2], ["Banking Software", 1]], 
    "Accounting" => [["Offshore", 1], ["ACCA", 1]] 
} 
] 

。どんな助けもありがたい。

+1

「成功なし」とはどういう意味ですか?それは動作しませんでしたか?それはあなたに無効な出力を与えましたか? – Makoto

+0

書かれているように、これは「私のためのコードを書いてください」という質問です。私はあなたが立ち往生した場所を過ぎ去るのを手伝いたいと思っていますが、詳細を分かち書きしなければ助けません。 –

答えて

2

コードと例

[arr.each_with_object(Hash.new(0)) { |pair, h| h[pair] += 1 }. 
    each_with_object(Hash.new { |h,k| h[k]=[] }) { |((a,b),n),g| g[a] << [b,n] }] 
    #=> [{"IT"=>[["Testing", 3], ["Banking Software", 1], ["ERP", 2], ["IT Security", 2]], 
    # "Accounting"=>[["Offshore", 1], ["ACCA", 1]]}] 

(むしろ単にハッシュよりも)単一のハッシュを含む配列が所望される理由は明らかではありません。ハッシュがすべて必要な場合は、コード内の外側の括弧を削除するだけです。

Hash.new(0)

説明は時々カウントハッシュと呼ばれています。 (Hash::newを参照してください。)キー:catを持っていない場合はh = Hash.new(0)hh[:cat]ハッシュを変更せずに、(ここではゼロ)のデフォルト値を返します。

h[:cat] = h[:cat] + 1 

hがキー:catを持っている場合は、平等の右側にh[:cat]は、そのキーの現在の値であり、8言う:Rubyはh[:cat] += 1に遭遇すると、それが最初に行うことはにその式を拡張しています。一方

h[:cat] = 8 + 1 #=> 9 

を計算hキー:catを持っていない場合、私たちは、その後、右のh[:cat]がデフォルト値に設定されているので、私たちは最初に、そのため

h[:cat] = 0 + 1 #=> 0 

を持っています次のようにステップ私たちは、ハッシュを計算:

g = arr.each_with_object(Hash.new(0)) { |pair, h| h[pair] += 1 } 
    #=> {["IT", "Testing"]=>3, ["IT", "Banking Software"]=>1, ["IT", "ERP"]=>2, 
    # ["IT", "IT Security"]=>2, ["Accounting", "Offshore"]=>1, ["Accounting", "ACCA"]=>1} 

これは簡単な形式

とほぼ同じである
h = {} 
arr.each do |pair| 
    h[pair] = 0 unless h.key?(pair) 
    h[pair] += 1 
end 
    #=> [["IT", "Testing"], ["IT", "Banking Software"], ["IT", "ERP"], 
    # ["IT", "Testing"], ["IT", "IT Security"], ["IT", "ERP"], 
    # ["IT", "IT Security"], ["Accounting", "Offshore"], ["IT", "Testing"], 
    # ["Accounting", "ACCA"]] 
h #=> {["IT", "Testing"]=>3, ["IT", "Banking Software"]=>1, ["IT", "ERP"]=>2, 
    # ["IT", "IT Security"]=>2, 
    # ["Accounting", "Offshore"]=>1, ["Accounting", "ACCA"]=>1} 

eachは受信者を返しますので、このスニペットがメソッドでラップされている場合は、最後にhという行が必要です。

第2ステップ(ちょうど計算されたhを使用)は、以下を実装したことが素晴らしいことでした。等式の右側のh[k]メソッドHash#[]ある一方h[k] =は、方法Hash#[]=ため構文糖あること

g = {} 
h.each do |k,n| 
    a, b = k 
    g[a] = [] unless g.key?(a) 
    g[a] << [b, n] 
end 
g # => {"IT"=>[["Testing", 3], ["Banking Software", 1], ["ERP", 2], ["IT Security", 2]], 
    #  "Accounting"=>[["Offshore", 1], ["ACCA", 1]]} 

1注意。

0

私は宿題に答えるつもりはありませんが、ここではあなたのためにいくつかの擬似コードは次のとおりです。

output = {} 

yourarray.each { |item| 
    // Key will be "IT" for the first iteration 
    key = item[0]; 
    // Value will be "Testing" for the first iteration 
    value = item[1]; 
    // Now you want to set Output['IT'] to 1 
    // If Output['IT'] was already set, then you need to increment the number 
} 
+0

これは私の宿題ではありません! –

1

ない非常に何を望んでいたが、私はこれが役立つと確信している:

arr.group_by(&:first).transform_values { |arr| arr.map { |sub| sub.last } 
                .group_by(&:itself) 
                .map { |k,v| [k, v.size] } 
             } 


#=> { "IT"   => [["Testing", 3], 
#      ["Banking Software", 1], 
#      ["ERP", 2], 
#      ["IT Security", 2]], 
#  
#  "Accounting" => [["Offshore", 1], 
#      ["ACCA", 1]] 
# } 

あなたはそれを私が想定しているアレイでプッシュすることができ、ボブはあなたの叔父のものです。


重要な方法:transform_values; group_byおよびmap。詳細については、www.ruby-doc.orgを参照してください。