2012-11-13 153 views
4

這個問題是非常非常具體的情況下,我可能會改變params。這不是任何Rails應用程序的一部分。ruby​​合併兩個語句到一個

params爲{:email => " ab", :xyz => " ", :opq => nil} 我運行以下:

params.each{|_, v| v.strip! if v} 
params.keep_if{|_, v| v.length > 0 if v} 

得到PARAMS作爲 {:email => "ab"}

反正是有合併上述兩行成一個?

+3

我會認爲這是壞的形式發生變異的'params'對象軌道。改用一個返回新散列的方法。就像說'哈希#選擇'一樣。 –

+0

是的,刪除換行並插入一個點;-)'params.each {| _,v | v.strip!如果v} .keep_if {| _,v | v.length> 0如果v}' – tokland

回答

4
ruby-1.9.3-p125 :011 > params ={:email => " ab", :xyz => " ", :opq => nil} 
=> {:email=>" ab", :xyz=>" ", :opq=>nil} 
ruby-1.9.3-p125 :012 > params.reject! { |_, v| !v || v.strip!.length == 0 } 
=> {:email=>"ab"} 
+1

使用'strip!'來匹配提問者的期望值。 –

+0

是不是使這個優雅的複雜性,他想要選擇特定的元素*和*在一個語句中轉換它們(條)? – spike

+0

@Dave它不會改變參數。我必須接受中間變量的幫助。 'ab = params.select {| _,v | v && v.strip.length> 0}'然後是'params = ab'這樣仍然有兩行 – JVK

1
params.each{|_, v| v.strip! if v}.reject!{|_, v| !v || v.length == 0} 
+1

除非有很好的需求,否則我會避免使用副作用函數:在這種情況下,我不能辯論存在(但可以在這裏爭辯不是)。 – 2012-11-13 21:37:20

0

其實,你寫的線可鏈接:

params.each{|_, v| v.strip! if v}.keep_if{|_, v| v.length > 0 if v} 

這工作,因爲each回報率(這是更新)對象本身。但是,恕我直言就地更新通常是一個壞主意,所以這裏是一個功能的方法:

params2 = Hash[params.map { |k, v| [k, v.strip] if v && v.strip.size > 0 }.compact] 

但由於缺乏STDLIB一些基本的抽象,這是不必要的冗長。隨着Enumerable#mashObject#present?援助它的那樣簡單:

params2 = params.mash { |k, v| [k, v.strip] if v.present? } 
0

這裏,似乎在技術上回答你的問題一個選項,但我猜測它是不是你在找什麼:

params.select{|_,v| v.strip.length > 0 if v} 

你遇到的根本麻煩是,哈希#map不是而是返回一個哈希值,而是一個數組。包括我在內的許多人都覺得這很煩人。例如見:http://www.ruby-forum.com/topic/185611

這是一個使用注入的詳細選項。

params.inject({}) {|h,(k,v)| h.merge(k => v ? v.strip : v)}.select{|_,v| v.length > 0 if v} 

如果對您很重要,這些解決方案都不會對參數進行任何破壞性更改。

1.9.3-p125 :030 > params = {:email => " ab", :xyz => " ", :opq => nil} 
=> {:email=>" ab", :xyz=>" ", :opq=>nil} 
1.9.3-p125 :031 > params.inject({}) {|h,(k,v)| h.merge(k => v ? v.strip : v)}.select{|_,v| v.length > 0 if v} 
=> {:email=>"ab"} 
1.9.3-p125 :032 > params 
=> {:email=>" ab", :xyz=>" ", :opq=>nil} 

注入是一個棘手的功能,需要一些習慣。我會盡力解釋一步此行步:

  • params.inject({}}說,創建一個空的哈希存儲在我們的結果
  • | H,(K,V)|表示將新的空散列傳遞給變量h,同時還將原始參數散列中的鍵值對分別傳遞給k,v。

接下來它得到了很多毛。我會從內到外解開下一個命令。

  • v ? v.strip : v使用三元運算符返回v。在v計算結果爲true或v在訴案件的情況下條是假的或零

  • k => v ? v.strip : v創建,結果一個新的哈希

  • h.merge(k => v ? v.strip : v)合併我們的新散列成H,開始是空的,然後將結果傳遞給注入循環的下一次迭代。

  • 在循環的下一次迭代中,h將不再爲空,未來的結果將繼續合併到它。

在這一點上,我們已經剝離了哈希,如果我們停在這裏的結果看起來是這樣的:

1.9.3-p125 :032 > params 
=> {:email=>" ab", :xyz=>" ", :opq=>nil} 
1.9.3-p125 :033 > params.inject({}) {|h,(k,v)| h.merge(k => v ? v.strip : v)} 
=> {:email=>"ab", :xyz=>"", :opq=>nil} 

現在散列被剝離,select語句是直線前進。我使用select而不是keep_if,因爲儘管缺少!,keep_if是一種破壞性的方法。看到這個咆哮:http://news.ycombinator.com/item?id=2247352。由於我們的注入語句返回一個散列,我們可以直接調用.select,儘管我不建議在實際操作中將您的代碼行長這麼長。

1.9.3-p125 :034 > params 
=> {:email=>" ab", :xyz=>" ", :opq=>nil} 
1.9.3-p125 :035 > params.inject({}) {|h,(k,v)| h.merge(k => v ? v.strip : v)}.select{|_,v| v.length > 0 if v} 
=> {:email=>"ab"} 
0
params.keys.each{|k| v = h.delete(k); h[k] = v.strip if v and !v.empty?} 

params.select!{|k, v| v and v.strip!; v and !v.empty?}