Slicing params hash for specific values

故事扮演 提交于 2019-11-29 03:35:26

I changed by mind. The previous one doesn't seem to be any good.

class Hash
  def slice1(*keys)
    keys.each_with_object({}){|k, h| h[k] = self[k]}
  end
  def slice2(*keys)
    h = {}
    keys.each{|k| h[k] = self[k]}
    h
  end
end
Blake Taylor

I would just use the slice method provided by active_support

require 'active_support/core_ext/hash/slice'
{a: 1, b: 2, c: 3}.slice(:a, :c)                  # => {a: 1, c: 3}

Of course, make sure to update your gemfile:

gem 'active_support'

Sequel has built-in support for only picking specific columns when updating:

product.update_fields(params, [:name, :description])

That doesn't do exactly the same thing if :name or :description is not present in params, though. But assuming you are expecting the user to use your form, that shouldn't be an issue.

I could always expand update_fields to take an option hash with an option that will skip the value if not present in the hash. I just haven't received a request to do that yet.

Perhaps

class Hash
  def slice *keys
    select{|k| keys.member?(k)}
  end
end

Or you could just copy ActiveSupport's Hash#slice, it looks a bit more robust.

Here are my implementations; I will benchmark and accept faster (or sufficiently more elegant) solutions:

# Implementation 1
class Hash
  def slice(*keys)
    Hash[keys.zip(values_at *keys)]
  end
end

# Implementation 2
class Hash
  def slice(*keys)
    {}.tap{ |h| keys.each{ |k| h[k]=self[k] } }
  end
end

# Implementation 3 - silently ignore keys not in the original
class Hash
  def slice(*keys)
    {}.tap{ |h| keys.each{ |k| h[k]=self[k] if has_key?(k) } }
  end
end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!