2010-11-24 2 views
1

hash2의 값과 hash2의 값의 교차점을 만들려고합니다. 그 값이 같은 키를 공유한다면. 지금까지 제 코드가 있습니다. 나는 두 개의 해시 -> data와 data1을 생성 할 수있다. 두 개의 키 값이 같은 경우, 두 개의 별도 해시 키가 같은 경우 교차점을 만듭니다. 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에서 해당 값을 제거, 또한 hash2에서 그 동일한 키의 존재 만 값을 유지, hash1에서 각 키입니다. 나는 Hash1에 존재하지 않는 Hash2에 존재하는 어떤 키들에 대해서도 염려하지 않는다.

"&"과 "set"을 사용하여 배열을 교차시킬 수 있다는 것을 알고 있습니다 만, 지금까지 스크립트에서이를 수행 할 수 없었습니다.

조언이 도움이 될 것입니다. 감사.

테오의 경우 :

예. [k, l, m, n, o], delta : [p, b, c, d, e] , R]}

hash2 {알파 [A, C, Q, Z, 브라보 : Z, X, 찰리 : K, L, M, N]}

따라서 교차 이런 식으로 보일거야.

hash3 {알파 [A, C, 브라보 [닐, 찰리 : K, L, M, N]} 두 해시 일반 교차로

+0

hash2에없는 hash1의 키는 어떻게됩니까? –

+0

원하는 내용을 쉽게 해독 할 수 없습니다. 두 개의 해시가 어떻게 보이고 어떤 것을 얻고 싶은지에 대한 간단한 예제를 제공 할 수 있습니까? – Theo

+0

예, 그 가능성을 포함하는 것을 잊었습니다. 이 경우 hash1의 키를 제거해야합니다. – user511038

답변

1

가 수행

Hash[h1.to_a & h2.to_a] 

하지만 귀하의 사례는 조금 다릅니다. 당신은 당신이 코드를 찾고있는 교차로 얻을 수 있습니다 :

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]} 

귀하의 예는 :bravo => [nil]을 포함,하지만 나는 nilhash1hash2:bravo 키 사이의 공통 요소가 아니므로 그 오류라고 생각합니다, 그래서 말이되지 않습니다. hash1hash2에 있지만 값 목록에 공통 요소가없는 키의 빈 목록을 원하면 세 번째 행을 제거 할 수 있습니다. 그렇지 않은 경우 세 번째 행을 제거 할 수 있습니다.

+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

안녕하세요. 도와 주셔서 감사합니다. 솔루션을 실행하려고하면 오류가 발생합니다. "intersection.rb : 23 :'[] ': 해시 (ArgumentError)의 홀수 인수 \t intersection.rb : 23" – user511038

+0

지금 당신의 솔루션을 사용할 수 있습니다. 그러나 계속 살펴 봐야 할 필요가 있다고 생각합니다. 그것은 값의 진정한 교차점을 생성하지 않기 때문에. 다시 한 번 감사드립니다! – user511038

+0

@ user511038 : 질문에 샘플 데이터가없고 테스트 사례가없고 예제가 실행되지 않고 코드에서 수행 할 내용을 지정하지 않았으며 게시 한 코드가 질문과 관련이없는 것으로 나타났습니다 (심지어 만약 * 않았다 *, 당신이 게시하지 않은 외부 파일에 따라 다르기 때문에 어떤 도움이되지 않을 것입니다), 나는 내 최고의 암호 해독을 해봤 어. 내가 잘못 해석 한 것이 있으면 알려주세요. 고칠 수 있습니다. –

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

또한 h1.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

관련 문제