0

在Ruby中,我以这种方式通过键名选择一些哈希值

new_values = my_hash.values_at(:value2, :value3, :value6, :value8).select {|a| !a.empty?}

那这个呢?它不工作。

new_values = my_hash.values_at(:value2, :value3, :value6, :value8).select(&:!empty?)
4

5 回答 5

4

正如 Sergio 解释的那样,标准 Ruby 无法做到这一点,因为您使用的表达式不会解析。一个人可以一起破解一些东西,所以它可以工作(当然reject是这里的方法):

['1', '', '11', ''].select(&fn(:empty?, :!))
#=> ["1", "11"]

这是fn我的扩展库中使用的实现:

def fn(*funs)
  -> x do
    funs.inject(x) do |v,f|
      Proc === f ? f.call(v) : v.send(f)
    end
  end
end
于 2012-09-04T10:30:35.493 回答
3

它不起作用,因为没有带有 name 的方法!empty?。这个名字在红宝石中是非法的,AFAIK。您要么必须使用完整的 lambda 形式(如在您的第一个片段中)或使用reject

['1', '', '11', ''].select(&:empty?) # => ["", ""]
['1', '', '11', ''].reject(&:empty?) # => ["1", "11"]
于 2012-09-04T10:20:58.840 回答
1

谈论替代品:

Not = 
  lambda do |x|
    p = x.to_proc 
    lambda do |*ys|
      !p[*ys]
    end
  end

['1', '', '11', ''].select(&Not[:empty?])

可以很容易地扩展到更有趣的情况,如组合、扇出。

于 2012-09-04T13:54:21.800 回答
0

的逆方法empty?any?。有了它,你可以通过使用来实现你的目标

new_values = my_hash.values_at(:value2, :value3, :value6, :value8).select(&:any?)
于 2012-09-04T10:44:46.003 回答
0

本着我在这里回答的精神:

class Symbol
  def on
    ->(*args) { yield(*args).send(self) }
  end
end

['1', '', '11', ''].select(&:!.on(&:empty?))
# => ["1", "11"] 
于 2014-06-03T08:49:53.617 回答