ruby将两个语句合并为一个

时间:2012-11-13 21:28:06

标签: ruby

这个问题适用于非常具体的案例,我可以更改params。这不是任何rails应用程序的一部分。

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

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

获得参数 {:email => "ab"}

无论如何将上面两行合并成一个?

5 个答案:

答案 0 :(得分: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 :(得分:1)

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

答案 2 :(得分: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? }

答案 3 :(得分:0)

这是一个似乎在技术上回答你的问题的选项,但我猜它不是你想要的:

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

你遇到的根本问题是Hash #map确实返回一个哈希而是一个数组。许多人,包括我自己,都觉得这很烦人。例如,请参阅:http://www.ruby-forum.com/topic/185611

这是一个使用inject的详细选项。

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

如果对您很重要,这些解决方案都不会对params进行任何破坏性更改。

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.strip,如果v计算结果为true,则v为v或false

  • 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。由于我们的inject语句返回一个哈希值,我们可以直接在其上调用.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"} 

答案 4 :(得分: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?}