新手问题 如何快速判断一个 hash 里是否有 nil 或者空值

QueXuQ · 2014年03月23日 · 最后由 leozwa 回复于 2014年03月24日 · 8646 次阅读

假如我有一个 hash 的结构是这样的:

@a = {
  b: "xx", 
  c: "xxx",
  ...
}

限制传过一个 params[:a] 过来,怎么写最方便遍历一遍这个 hash 的值和@a比,里面的键值都存在,并且都不为空?

我限制写法是:

true if params[:a][:b].present? && params[:a][:c].present?  &&..

这样写法 hash 多的话,就非常的长,不知道有没有更好的写法?

a = {
  b: "xx", 
  c: nil
}

p a.any?{|k,v| v==nil}

行不行?

#1 楼 @chenge 准确来说,这样判断还不够。因为我上面说的 a 和 params[:a] 不是同一个,a 可能有 c 这个键值,而 params[:a] 可能会没有 c,而不是 c=nil,a 相当于 params[:a] 的字典。

#1 楼 @chenge 还会有这样的情况:

a = {
  b: "xxx",
  c: "lll",
  d: "ooo",
  f: "ui"
}
params[:a] ={
   b: "x",
   d: "ds"
   g: "kds"
   f: ""
}

我想要知道 params[:a] 和 a 比较,a 存在的键值,params[:a] 是否为空或者不存在,而 params[:a] 有,a 没有的键值则不需要管。

a.all? { |key, _| params[:a][key].present? }
a = {
  b: "xxx",
  c: "lll",
  d: "ooo",
  f: "ui"
}

params = {}

params[:a] = {
   b: "x",
   c: "c",
   d: "ds",
   f: "f",
   g: "g"
}

params[:b] = {
   b: "x"
}

params[:c] = {
   b: "x",
   c: "c",
   d: "ds",
   f: "",
   g: "g"
}

def not_empty(str)
  str.to_s.strip.length != 0
end

a.all? { |key, _| params[:a].has_key?(key) && not_empty(params[:a][key]) } # => true
a.all? { |key, _| params[:b].has_key?(key) && not_empty(params[:b][key]) } # => false
a.all? { |key, _| params[:c].has_key?(key) && not_empty(params[:c][key]) } # => false

@rei的方法改的,有 ActiveSupport 的话,用 present?就行。

先把这两 hashkeys 取出来,然后判断这两 keys 的长度是否相同以及内容 是否全等,之后再进行取元素的判断的话从效率来看是否要好些?

#4 楼 @Rei #7 楼 @swordray

难道不应该是

a.all? { |key, _| params[:a][key].present? }

一个参数把键/值都迭代了。

#8 楼 @willmouse 还真是,不写第二个参数就混一起了,已修正。

...你的描述方式好奇怪。。。是只比较键……不管值吗。。。这样行不

(a.keys <=> params[:a].keys) >= 0

不过前提是你得确保键的形式是一致的。。。

#8 楼 @willmouse 看漏了,以为是

a.keys.all? { |key| params[:a][key].present? }

你们在干什么?.....

hash.values.include?(nil)

#13 楼 @karmue 请认真读 LZ 的需求... 你这个不能确认 key 在不在...

需要 登录 后方可回复, 如果你还没有账号请 注册新账号