2013-07-12 23 views
8

Ben iki karmaları:İki karma kesimin kesişimini nasıl oluştururum?

hash3 = {3 => "hello" , 4 => "world"} 

herhangi döngü olmadan bunu mümkün mü:

hash1 = {1 => "a" , 2 => "b" , 3 => "c" , 4 => "d"} 
hash2 = {3 => "hello", 4 => "world" , 5 => "welcome"} 

ben her iki sağlamalarının ortak anahtarları içeren bir karma ihtiyaç?

+1

* herhangi döngü olmadan * hayır. Neden döngüler kullanmak istemiyorsun? – Shoe

+3

Sanırım "döngüyü kendim kodlamadan ve yerleşik bir yöntem kullanmadan" anlamına gelir. – Koraktor

+2

Değerlerin ne olduğuyla ilgileniyor musunuz, yoksa sadece tuşların verilen karma tuşların kesişme noktaları mı? –

cevap

12
hash3 = hash1.keep_if { |k, v| hash2.key? k } 

Bu, söz konusu koduyla aynı etkiye sahip olmayacaktır, bunun yerine döndürür:

hash3 #=> { 3 => "c", 4 => "d" } 

sağlamalarının sırası burada önemlidir. Değerler her zaman #keep_if'un gönderildiği kareden alınacaktır.

hash3 = hash2.keep_if { |k, v| hash1.key? k } 
#=> {3 => "hello", 4 => "world"} 
+1

, hash3 = {3 => "c", 4 => "d"} değerini verir, ancak user require- hash3 = {3 => "merhaba", 4 => "dünya"} –

+0

Düzenlenmiş cevabımı görün. – Koraktor

+0

evet şimdi, cevap için –

9

Bununla gider:

için biraz azaltılabilir
hash1 = {1 => "a" , 2 => "b" , 3 => "c" , 4 => "d"} 
hash2 = {3 => "hello", 4 => "world" , 5 => "welcome"} 

Hash[(hash1.keys & hash2.keys).zip(hash2.values_at(*(hash1.keys & hash2.keys)))] 
=> {3=>"hello", 4=>"world"} 

: Dizisinin & yönteminde

keys = (hash1.keys & hash2.keys) 
Hash[keys.zip(hash2.values_at(*keys))] 

hiledir. Belgeler şöyle diyor:

Kesiştirme Ayarı - İki dizide ortak olan ve çoğaltmalar hariç, yeni bir dizi içeren yeni bir dizi döndürür. Sipariş, orijinal diziden korunur.

require 'benchmark' 

HASH1 = {1 => "a" , 2 => "b" , 3 => "c" , 4 => "d"} 
HASH2 = {3 => "hello", 4 => "world" , 5 => "welcome"} 

def tinman 
    keys = (HASH1.keys & HASH2.keys) 
    Hash[keys.zip(HASH2.values_at(*keys))] 
end 

def santhosh 
    HASH2.select {|key, value| HASH1.has_key? key } 
end 
def santhosh_2 
    HASH2.select {|key, value| HASH1[key] } 
end 

def priti 
    HASH2.select{|k,v| HASH1.assoc(k) } 
end 

def koraktor 
    HASH1.keep_if { |k, v| HASH2.key? k } 
end 
def koraktor2 
    HASH2.keep_if { |k, v| HASH1.key? k } 
end 

N = 1_000_000 
puts RUBY_VERSION 
puts "N= #{N}" 

puts [:tinman, :santhosh, :santhosh_2, :priti, :koraktor, :koraktor2].map{ |s| "#{s.to_s} = #{send(s)}" } 
Benchmark.bm(11) do |x| 
    x.report('tinman') { N.times { tinman() }} 
    x.report('santhosh_2') { N.times { santhosh_2() }} 
    x.report('santhosh') { N.times { santhosh() }} 
    x.report('priti') { N.times { priti() }} 
    x.report('koraktor') { N.times { koraktor() }} 
    x.report('koraktor2') { N.times { koraktor2() }} 
end 

Yakut 1.9.3-p448

:

1.9.3 
N= 1000000 
tinman = {3=>"hello", 4=>"world"} 
santhosh = {3=>"hello", 4=>"world"} 
santhosh_2 = {3=>"hello", 4=>"world"} 
priti = {3=>"hello", 4=>"world"} 
koraktor = {3=>"c", 4=>"d"} 
koraktor2 = {3=>"hello", 4=>"world"} 
        user  system  total  real 
tinman  2.430000 0.000000 2.430000 ( 2.430030) 
santhosh_2 1.000000 0.020000 1.020000 ( 1.003635) 
santhosh  1.090000 0.010000 1.100000 ( 1.104067) 
priti   1.350000 0.000000 1.350000 ( 1.352476) 
koraktor  0.490000 0.000000 0.490000 ( 0.484686) 
koraktor2  0.480000 0.000000 0.480000 ( 0.483327) 

Ruby 2.0 altında Koşu İşte


Bunu yapmanın en etkili yoludur göstermek için bazı kriterler vardır .0-p247:

2.0.0 
N= 1000000 
tinman = {3=>"hello", 4=>"world"} 
santhosh = {3=>"hello", 4=>"world"} 
santhosh_2 = {3=>"hello", 4=>"world"} 
priti = {3=>"hello", 4=>"world"} 
koraktor = {3=>"c", 4=>"d"} 
koraktor2 = {3=>"hello", 4=>"world"} 
        user  system  total  real 
tinman  1.890000 0.000000 1.890000 ( 1.882352) 
santhosh_2 0.710000 0.010000 0.720000 ( 0.735830) 
santhosh  0.790000 0.020000 0.810000 ( 0.807413) 
priti   1.030000 0.010000 1.040000 ( 1.030018) 
koraktor  0.390000 0.000000 0.390000 ( 0.389431) 
koraktor2  0.390000 0.000000 0.390000 ( 0.389072) 

Koraktor'un orijinal kodu çalışmıyor, ancak ikinci kod geçişiyle güzelce çevrildi ve en iyi hızla ilerliyor. key?'un ne gibi etkileri olacağını görmek için santhosh_2 yöntemini ekledim. Rutini biraz hızlandırdı, ama Koraktor'lara yetişmek için yeterli değildi.


Sadece dokümantasyon amaçlı, ben de key? yöntemini kaldırmak Koraktor ikinci kod tweaked ve ondan daha fazla zaman tıraş etti. Burada eklenen yöntemi ve yeni çıkış var:

def koraktor3 
    HASH2.keep_if { |k, v| HASH1[k] } 
end 

1.9.3 
N= 1000000 
tinman = {3=>"hello", 4=>"world"} 
santhosh = {3=>"hello", 4=>"world"} 
santhosh_2 = {3=>"hello", 4=>"world"} 
priti = {3=>"hello", 4=>"world"} 
koraktor = {3=>"c", 4=>"d"} 
koraktor2 = {3=>"hello", 4=>"world"} 
koraktor3 = {3=>"hello", 4=>"world"} 
        user  system  total  real 
tinman  2.380000 0.000000 2.380000 ( 2.382392) 
santhosh_2 0.970000 0.020000 0.990000 ( 0.976672) 
santhosh  1.070000 0.010000 1.080000 ( 1.078397) 
priti   1.320000 0.000000 1.320000 ( 1.318652) 
koraktor  0.480000 0.000000 0.480000 ( 0.488613) 
koraktor2  0.490000 0.000000 0.490000 ( 0.490099) 
koraktor3  0.390000 0.000000 0.390000 ( 0.389386) 

2.0.0 
N= 1000000 
tinman = {3=>"hello", 4=>"world"} 
santhosh = {3=>"hello", 4=>"world"} 
santhosh_2 = {3=>"hello", 4=>"world"} 
priti = {3=>"hello", 4=>"world"} 
koraktor = {3=>"c", 4=>"d"} 
koraktor2 = {3=>"hello", 4=>"world"} 
koraktor3 = {3=>"hello", 4=>"world"} 
        user  system  total  real 
tinman  1.840000 0.000000 1.840000 ( 1.832491) 
santhosh_2 0.720000 0.010000 0.730000 ( 0.737737) 
santhosh  0.780000 0.020000 0.800000 ( 0.801619) 
priti   1.040000 0.010000 1.050000 ( 1.044588) 
koraktor  0.390000 0.000000 0.390000 ( 0.387265) 
koraktor2  0.390000 0.000000 0.390000 ( 0.388648) 
koraktor3  0.320000 0.000000 0.320000 ( 0.327859) 
+0

Thanx çalışıyor, işe yarıyor ........ – user2575339

+0

Teşekkürler. Karşılaştırmaya bak. user2564200'ün kodu, küçük bir tweak ile, en hızlıdır. –

+0

Korator en hızlıdır. Ben sizin ölçütünüzü yazdıktan sonra kodunuzu değiştirdiniz, bu yüzden sizinki 'Hash [] 'ı kullanarak yansıtırken, orijinal olarak düzenleme tarihinde kanıtlandığı gibi“ assoc ”kullanılır. –

8
hash2.select {|key, value| hash1.has_key? key } 
# => {3=>"hello", 4=>"world"} 
+1

Bu sitede gördüğüm en zarif çözüm bu. – Fuser97381

İlgili konular