2011-04-05 59 views
1

此方法只是更改找到的任何player_id的id。 Reek討厭它,但我找不到一種有意義的方式來重構它。使用克隆時,如何擺脫ruby中的重複?

(1..9).each { |n| 
    n = n.to_s 
    self.player_ids[n] = self.site_id.clone << "_" << self.player_ids[n].clone if self.player_ids[n]   
} 

難道我只是有這種重複的生活,因爲克隆功能不允許我:

player_id = self.player_ids[n] 
player_id = self.site_id.clone << "_" << player_id.clone if player_id 

樣品輸入:

{:player_ids => {"2" => "player_name1", "6" => "player_name4", "9" => "player_name9"} 

輸出:

{:player_ids => {"2" => "PRE_player_name1", "6" => "PRE_player_name4", "9" => "PRE_player_name9"} 
+1

你可以試試'self.site_id +「_」+ self.player_ids [n] if self.player_ids [n]'? – Dogbert 2011-04-05 13:59:35

+0

這個克隆和就地東西看起來很糟糕。你確定你想要嗎?爲什麼不向我們展示一個(或更多)pair輸入/ desired_output,以便我們能夠弄清楚你想要什麼。 – tokland 2011-04-05 14:30:30

+0

對不起,我應該養成顯示輸入和輸出的習慣。 – 2011-04-05 14:42:18

回答

1

這裏有兩種可能性樂技術,根據您的樣品輸入和輸出:

site_id = 'PRE' 
prefix = "#{site_id}_" 
h = {:player_ids => {"2" => "player_name1", "6" => "player_name4", "9" => "player_name9"}} 

# If mutating the original hash is not OK 
h2 = h.dup 
h2[:player_ids] = Hash[ h[:player_ids].map{ |s,n| [s, n.sub(/^/,prefix)] } ] 
p h, h2 
#=> {:player_ids=>{"2"=>"player_name1", "6"=>"player_name4", "9"=>"player_name9"}} 
#=> {:player_ids=>{"2"=>"PRE_player_name1", "6"=>"PRE_player_name4", "9"=>"PRE_player_name9"}} 

# If mutating the original hash is OK 
h[:player_ids].each{ |id_string,name| name.sub! /^/, prefix } 
p h 
#=> {:player_ids=>{"2"=>"PRE_player_name1", "6"=>"PRE_player_name4", "9"=>"PRE_player_name9"}} 

如果這不是你想要的,請編輯你的問題的樣本輸入/輸出和發佈評論澄清您的需求。

+0

謝謝!如果site_id =「PRE」,是否有更好的方法將它追加到子目錄site_id.clone <<「_」? Metrical似乎恨我經常使用克隆。 – 2011-04-05 16:01:58

+0

@JeremySmith我已經編輯了包含'site_id'作爲變量的答案。 – Phrogz 2011-04-05 16:09:37

1

#clone只是必需的,因爲您正在字符串上使用變異操作(<<)。使用字符串插值可以防止不必要的克隆,並使代碼更具慣用性。

player_ids[n] &&= "#{site_id.clone}_#{player_ids[n]}" 

作爲獎勵,我刪除你不需要的引用self和更換你的,如果有和平等。