【问题标题】:Is there a more efficient way of returning a hash value given array of keys if hash key/value is present?如果存在哈希键/值,是否有更有效的方法来返回给定键数组的哈希值?
【发布时间】:2017-08-10 01:31:01
【问题描述】:

我有一个接受散列的方法,并且我有一个键数组(按偏好排序),我想检查散列并返回找到的第一个匹配键的值,它不是blank?。到目前为止,我有以下内容,但由于我大量使用这种方法,我想知道是否有更有效的方法来解决它?

result = [:title, :name, :identifier, :slug].each do |key|
            if my_hash[key].present?
              return my_hash[key]
              break
            end
          end 

所以给出以下哈希:

{
  id: 10,
  title: "",
  name: "Foo",
  slug: "foo"
}

我希望result 是:“Foo”

【问题讨论】:

  • 你写道你想要一个键/值对,但你的代码只返回值。你真正想要哪个?
  • 为清楚起见进行了编辑-我想要在给定键的有序列表的情况下找到的第一个键的值。散列可能有部分或全部键,有时散列可能有键,但没有值(或者更确切地说不是truthy 值)
  • 沿着你的代码行,你也可以做break my_hash[key]

标签: ruby-on-rails ruby


【解决方案1】:

从效率的角度来看,您的方式可能接近最佳。但是如果你想让它更优雅,保持效率,那么:

my_hash[%i[title name identifier slug].find{|key| my_hash[key].present?}]

【讨论】:

    【解决方案2】:

    您可以执行以下操作:

    whitelisted_keys = [:title, :name, :identifier, :slug]
    filtered_hash = your_hash.slice(*whitelisted_keys) # will only get pair matching your whitelisted_keys
    
    # return all `.present?` key/values pairs:
    filtered_hash.select{ |k,v| v.present? }
    
    # return an array of the first key/value pair present:
    filtered_hash.find{ |k,v| v.present? } # append .last to get the value
    

    正如 Sawa 在评论中指出的那样,这不是最有效的方式,但可能更“可读”

    【讨论】:

    • 不错!我试图弄清楚如何使用slice,但我错过的是你的*whitelisted_keys。怎么样:your_hash[your_hash.slice(*whitelisted_keys).keys.first]
    • 这只会返回第一个列入白名单的键的值,可能不是present?
    • 这可能很优雅,但效率低于 OP。您正在创建一个中间哈希。此外,您正在调用 Rails 方法slice,这会降低代码效率。
    • @sawa 非常好,我通常更喜欢可读性,但正如 OP 所问,他正在寻找实现这一目标的最有效方法。
    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 2013-03-22
    • 2016-05-29
    • 1970-01-01
    • 2019-03-19
    • 2011-08-22
    • 2012-08-10
    • 2013-03-05
    相关资源
    最近更新 更多