2010-11-24 17 views
1

私はhash1の値とhash2の値との交差点を作成しようとしています。これらの値が同じキーを共有しているとします。ここまでは私のコードです。私は2つのハッシュ - > dataとdata1を生成することができます。だから、2つの独立したハッシュのキーが等しい場合、2つのキーの値の共通部分を作成します。 Ruby

#!/usr/bin/env ruby 

require 'pp' 
require 'set' 
data = {} 
File.read(ARGV[0]).each do |l| 
    l.chomp! 
    key, value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12 = l.split(/\s+/) 
    data[key] ||= {} 
    values = [value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12] 
    data[key] = values.compact! 

end 

data1 = {} 
File.read(ARGV[1]).each do |l| 
    l.chomp! 
    value = l.split(/\s+/) 
    data1[value[0]] ||= {} 
    data1[value[0]] = [value] 
end 

、私の主な目標はHASH1で各キーのためである、そうでない場合はHASH1からこれらの値を削除し、またHASH2でその同じキーで存在しているだけで、これらの値を保持します。私は、Hash1に存在しないHash2に存在するキーについては何も考慮していない。

"&"と "set"を使用して配列を交差させることができますが、これまでのスクリプトでこれを達成することはできませんでした。

アドバイスは素晴らしいでしょう。ありがとう。

テオの場合:

はい。
hash1 {alpha:[a、b、c、d、e]、bravo:[f、g、h、i、j]、チャーリー:[k、l、m、n、o]、デルタ:[p 、R]}

HASH2 {アルファ:[、C、Q、z]は、ブラボー:[Z、X]、チャーリー:[K、L、M、N]}

したがって、交差点このように見えるでしょう。

hash3 {アルファ:[C]、ブラボー:[ゼロ]、チャーリー:[K、L、M、N]} 2つのハッシュの規則的な交差を

+0

hash2に存在しないhash1のキーはどうすればよいですか? –

+0

あなたが望むものを解読することは容易ではありません。 2つのハッシュがどのように見えるか、そして何を得たいかの簡単な例を教えてください。 – Theo

+0

はい、その可能性を含めるのを忘れました。その場合、hash1のこれらのキーは削除する必要があります。 – user511038

答えて

1

を行う:

Hash[h1.to_a & h2.to_a] 

あなたのケースは少し異なります。あなたの例では、:bravo => [nil]を含むが、nilhash1hash2:bravoキーの間で共通の要素ではないので、私はそれが誤りだと思うので、それ

hash1 = {:alpha => [:a,:b,:c,:d,:e], :bravo => [:f,:g,:h,:i,:j], :charlie => [:k,:l,:m,:n,:o], :delta => [:p,:r]} 
hash2 = {:alpha => [:a,:c,:q,:z], :bravo => [:z,:x], :charlie => [:k,:l,:m,:n]} 

common_keys = hash1.keys & hash2.keys 
    # => [:alpha, :bravo, :charlie] 
intersection = common_keys.map { |k| [k, hash1[k] & hash2[k]] } 
    # => [[:alpha, [:a, :c]], [:bravo, []], [:charlie, [:k, :l, :m, :n]]] 
intersection = intersection.reject { |k, v| v.empty? } 
    # => [[:alpha, [:a, :c]], [:charlie, [:k, :l, :m, :n]]] 
Hash[intersection] 
    # => {:alpha=>[:a, :c], :charlie=>[:k, :l, :m, :n]} 

:あなたは、このコードで探している交差点を得ることができます意味がありません。 hash1hash2にあるキーの空のリストを必要とするが、値リストに共通の要素がない場合は、3番目の行を削除することができます。

+0

Theo、はい、正解です。ありがとうございました!唯一の例外は、私が{:b => [222]}したいということです。 – user511038

+0

あなたの質問にあなたが追加した例をよりよく反映するように答えを変更しました。 – Theo

+0

これがあなたが探していた答えであれば、それを受け入れられた答えとしてマークすることを検討してください。 – Theo

0
data = { a: [11], b: [22, 222], c: [33] } 
data2 = { b: [222, 2222], d: [4444] } 

Hash[data.map {|k, v| if data2[k] then [k, v & data2[k]] end }.compact] 
# => { b: [222] } 
+0

こんにちはJorg。助けてくれてありがとう。ソリューションを試してみるとエラーが表示されます。 "intersection.rb:23:' [] ':Hash(ArgumentError)の引数が奇数である \t intersection.rbから:23 " – user511038

+0

私は今あなたのソリューションを使用することができますが、それは値の真の交差を生成していないためです。再度、感謝します!! – user511038

+0

@ user511038:あなたの質問にはサンプルデータが含まれておらず、テストケースはなく、サンプル実行もなく、コードで何をしたいのかの指定もなく、投稿したコードはあなたの質問とは関係ないようですもしあなたが投稿していない外部ファイルに依存しているので、それは何の助けにもなりません)、あなたの秘密の解説を解読しました。私が誤解したことがあれば教えてください。私はそれを修正することができます。 –

0
Hash[h2.collect { |k,v| h1[k] ? [k, h1[k] & h2[k]] : [] }] 

また、あなたは最初h2.keysに比べh1.keysのサイズを確認してから最初の小さい方を反復処理します。上記の明快さは少し失われますが、大きさの違いがあるより大きいハッシュの方がはるかに優れています。

+0

こんにちはスティーブン。ありがとう!私は確かにこれを試してみましょう。それは有り難いです。 – user511038

0
def merge_hash(hash1, hash2) 
    result = {} 

    hash1.keys.each do |k| 
    result[k] = hash1[k] & hash2[k] unless hash2[k].nil? 
    end 
    result 
end 
+0

こんにちは。私はあなたのコードをまだ試していませんが、私は行います。ご協力ありがとうございました – user511038

関連する問題