【问题标题】:Delete array of keys in Ruby Hash删除 Ruby Hash 中的键数组
【发布时间】:2012-02-01 13:33:55
【问题描述】:

我将如何删除散列中的键数组?例如,您可以调用:

hash.delete(some_key)

但我该怎么做:

hash.delete([key1,key2,key3,...])

无需手动循环。

【问题讨论】:

  • 如果你有一个数组,那么无论如何你都会遍历它。也许您不需要将这些键存储在数组中,而是立即删除它们。

标签: ruby arrays hash


【解决方案1】:

您可以遍历一组键并删除它们中的每个人:

[key1, key2, key3].each { |k| some_hash.delete k }

想不起更好的解决方案了。

【讨论】:

  • 我试图远离循环,因为它们很慢,而且这段代码对时间很敏感。
  • 我明白了,但是如果您处理一组键,则无论如何都必须对其进行迭代。在您的情况下,哈希和数组的大小是多少?
  • 我真的不需要遍历键数组,只需要删除哈希中的那些键。哈希有大约 20,000 个项目,但它必须循环多次,每次项目都不同。
  • 我的意思是,您用于通过数组中的键从哈希中删除值的任何方法都需要遍历该数组(它至少会查看每个键)。这意味着计算时间至少与数组长度成线性关系(乘以从哈希中键删除的复杂度)。不过,我可能错了,我很乐意看到更好的解决方案。
  • 你循环数组一次;您多次搜索哈希(速度很快)。我尝试过这个;创建了一个包含 20_000 个随机 5 个字母单词的散列和一个包含 10_000 个 5 个字母单词的数组。 @KL-7 的行执行时间为 0.02 秒(这台计算机很旧)。
【解决方案2】:

这正是您正在寻找的... 您可以这样做,而无需不必要地遍历数组。

keys_to_delete = [key1, key2, key3]
hash_array.except!(*keys_to_delete)

结果存储在hash_array中

【讨论】:

  • 这是 rails 的一部分,不是 ruby​​。
【解决方案3】:

你可以尝试使用Hash#delete_if:

delete_if 从 hsh 中删除块计算为 true 的每个键值对。

array_hash.delete_if { |key, _| [key1, key2, key3].include? key }

更新 如果您不想遍历键数组,可以使用Set 而不是Array(因为Set 使用Hash 作为存储include? 是O(1)):

require 'set'
keys = [key1,key2,key3].to_set
array_hash.delete_if { |key, _| keys.include? key }

【讨论】:

  • +1。我只是要添加这个。当然,它也会遍历项目(甚至多次)。
  • 如果散列的大小远大于数组的大小,这种方法的效率低于遍历数组。
  • @KL-7,同意,在优化某些代码之前总是需要进行性能基准测试,没有测量的优化可能会增加执行时间和内存消耗。我不会费心优化这样的代码。 OP只有几个选择:)
【解决方案4】:

也许值得做一个方法

class Hash
  def delete_by_keys *keys
    keys.each{|k| delete(k)}
  end
end

hash_array.delete_by_keys(key1,key2,..)

【讨论】:

  • keys.map 而不是 keys.each 返回已删除的值数组。有用。
【解决方案5】:

ActiveSupport(Rails 的一部分)完全实现了这一点,如 Hash#except 和 Hash#except!

def except!(*keys)
    keys.each { |key| delete(key) }
    self
end

http://apidock.com/rails/v4.0.2/Hash/except%21

【讨论】:

    猜你喜欢
    • 2012-03-22
    • 2013-09-26
    • 1970-01-01
    • 2012-02-07
    • 2014-10-13
    • 2011-10-12
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多