跳至内容 跳至搜索

具有无关访问权限的哈希

实现一个哈希,其中键 :foo"foo" 被视为相同。

rgb = ActiveSupport::HashWithIndifferentAccess.new

rgb[:black] = '#000000'
rgb[:black]  # => '#000000'
rgb['black'] # => '#000000'

rgb['white'] = '#FFFFFF'
rgb[:white]  # => '#FFFFFF'
rgb['white'] # => '#FFFFFF'

在整个写入接口(调用 []=merge 等)中使用符号作为键时,内部会将其映射到字符串。此映射属于公共接口。例如,给定

hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)

保证键作为字符串返回

hash.keys # => ["a"]

从技术上讲,接受其他类型的键

hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
hash[0] = 0
hash # => {"a"=>1, 0=>0}

但此类适用于预期键为字符串或符号且将两者理解为相同的情况。例如 Ruby on Rails 中的 params 哈希。

请注意,核心扩展定义了 Hash#with_indifferent_access

rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access

这可能很方便。

要在 Rails 之外访问此类,请使用以下方法要求核心扩展

require "active_support/core_ext/hash/indifferent_access"

这反过来将要求此文件。

方法
#
A
C
D
E
F
H
I
K
M
N
R
S
T
U
V
W

类公共方法

[](*args)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 85
def self.[](*args)
  new.merge!(Hash[*args])
end

new(constructor = nil)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 70
def initialize(constructor = nil)
  if constructor.respond_to?(:to_hash)
    super()
    update(constructor)

    hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
    self.default = hash.default if hash.default
    self.default_proc = hash.default_proc if hash.default_proc
  elsif constructor.nil?
    super()
  else
    super(constructor)
  end
end

实例公共方法

[](key)

Hash#[] 相同,其中作为参数传递的键可以是字符串或符号

counters = ActiveSupport::HashWithIndifferentAccess.new
counters[:foo] = 1

counters['foo'] # => 1
counters[:foo]  # => 1
counters[:zoo]  # => nil
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 168
def [](key)
  super(convert_key(key))
end

[]=(key, value)

向哈希分配一个新值

hash = ActiveSupport::HashWithIndifferentAccess.new
hash[:key] = 'value'

此值稍后可以使用 :key'key' 提取。

别名:regular_writerstore
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 98
def []=(key, value)
  regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
end

assoc(key)

Hash#assoc 相同,其中作为参数传递的键可以是字符串或符号

counters = ActiveSupport::HashWithIndifferentAccess.new
counters[:foo] = 1

counters.assoc('foo') # => ["foo", 1]
counters.assoc(:foo)  # => ["foo", 1]
counters.assoc(:zoo)  # => nil
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 181
def assoc(key)
  super(convert_key(key))
end

compact()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 375
def compact
  dup.tap(&:compact!)
end

deep_stringify_keys()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 319
def deep_stringify_keys; dup end

deep_stringify_keys!()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 317
def deep_stringify_keys!; self end

deep_symbolize_keys()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 324
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end

default(key = (no_key = true))

Hash#default 相同,其中作为参数传递的键可以是字符串或符号

hash = ActiveSupport::HashWithIndifferentAccess.new(1)
hash.default                   # => 1

hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
hash.default                   # => nil
hash.default('foo')            # => 'foo'
hash.default(:foo)             # => 'foo'
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 223
def default(key = (no_key = true))
  if no_key
    super()
  else
    super(convert_key(key))
  end
end

delete(key)

从哈希中删除指定的键。

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 303
def delete(key)
  super(convert_key(key))
end

dig(*args)

Hash#dig 相同,其中作为参数传递的键可以是字符串或符号

counters = ActiveSupport::HashWithIndifferentAccess.new
counters[:foo] = { bar: 1 }

counters.dig('foo', 'bar')     # => 1
counters.dig(:foo, :bar)       # => 1
counters.dig(:zoo)             # => nil
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 208
def dig(*args)
  args[0] = convert_key(args[0]) if args.size > 0
  super(*args)
end

dup()

返回哈希的浅表副本。

hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
dup  = hash.dup
dup[:a][:c] = 'c'

hash[:a][:c] # => "c"
dup[:a][:c]  # => "c"
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 264
def dup
  self.class.new(self).tap do |new_hash|
    set_defaults(new_hash)
  end
end

except(*keys)

返回一个哈希,其中包含除给定键之外的所有内容。

hash = { a: "x", b: "y", c: 10 }.with_indifferent_access
hash.except(:a, "b") # => {c: 10}.with_indifferent_access
hash                 # => { a: "x", b: "y", c: 10 }.with_indifferent_access
别名:without
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 311
def except(*keys)
  dup.except!(*keys)
end

extractable_options?()

返回 true,以便 Array#extract_options! 找到此类的成员。

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 58
def extractable_options?
  true
end

fetch(key, *extras)

Hash#fetch 相同,其中作为参数传递的键可以是字符串或符号

counters = ActiveSupport::HashWithIndifferentAccess.new
counters[:foo] = 1

counters.fetch('foo')          # => 1
counters.fetch(:bar, 0)        # => 0
counters.fetch(:bar) { |key| 0 } # => 0
counters.fetch(:zoo)           # => KeyError: key not found: "zoo"
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 195
def fetch(key, *extras)
  super(convert_key(key), *extras)
end

fetch_values(*indices, &block)

返回指定索引处的值的数组,但当找不到其中一个键时也会引发异常。

hash = ActiveSupport::HashWithIndifferentAccess.new
hash[:a] = 'x'
hash[:b] = 'y'
hash.fetch_values('a', 'b') # => ["x", "y"]
hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 251
def fetch_values(*indices, &block)
  indices.map! { |key| convert_key(key) }
  super
end

has_key?(key)

别名:key?

include?(key)

别名:key?

key?(key)

检查哈希是否与传入的参数匹配的键

hash = ActiveSupport::HashWithIndifferentAccess.new
hash['key'] = 'value'
hash.key?(:key)  # => true
hash.key?('key') # => true
别名:include?has_key?member?
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 151
def key?(key)
  super(convert_key(key))
end

member?(key)

别名:key?

merge(*hashes, &block)

此方法具有与 update 相同的语义,但它不会修改接收器,而是返回一个具有合并结果的新哈希,并具有无差别访问权限。

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 273
def merge(*hashes, &block)
  dup.update(*hashes, &block)
end

merge!(*other_hashes, &block)

别名:update

nested_under_indifferent_access()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 66
def nested_under_indifferent_access
  self
end

regular_update(*other_hashes, &block)

别名:update

regular_writer(key, value)

别名:[]=

reject(*args, &block)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 332
def reject(*args, &block)
  return to_enum(:reject) unless block_given?
  dup.tap { |hash| hash.reject!(*args, &block) }
end

replace(other_hash)

用 other_hash 替换此哈希的内容。

h = { "a" => 100, "b" => 200 }
h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 298
def replace(other_hash)
  super(self.class.new(other_hash))
end

reverse_merge(other_hash)

类似于 merge,但方式相反:将接收器合并到参数中,并返回一个具有无差别访问权限的新哈希作为结果

hash = ActiveSupport::HashWithIndifferentAccess.new
hash['a'] = nil
hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
别名:with_defaults
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 283
def reverse_merge(other_hash)
  super(self.class.new(other_hash))
end

reverse_merge!(other_hash)

reverse_merge 语义相同,但会就地修改接收器。

别名:with_defaults!
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 289
def reverse_merge!(other_hash)
  super(self.class.new(other_hash))
end

select(*args, &block)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 327
def select(*args, &block)
  return to_enum(:select) unless block_given?
  dup.tap { |hash| hash.select!(*args, &block) }
end

slice(*keys)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 365
def slice(*keys)
  keys.map! { |key| convert_key(key) }
  self.class.new(super)
end

slice!(*keys)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 370
def slice!(*keys)
  keys.map! { |key| convert_key(key) }
  super
end

store(key, value)

别名:[]=

stringify_keys()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 318
def stringify_keys; dup end

stringify_keys!()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 316
def stringify_keys!; self end

symbolize_keys()

别名:to_options
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 322
def symbolize_keys; to_hash.symbolize_keys! end

to_hash()

转换为具有字符串键的常规哈希。

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 380
def to_hash
  _new_hash = Hash.new
  set_defaults(_new_hash)

  each do |key, value|
    _new_hash[key] = convert_value(value, conversion: :to_hash)
  end
  _new_hash
end

to_options()

别名:symbolize_keys

to_options!()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 325
def to_options!; self end

transform_keys(hash = NOT_GIVEN, &block)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 344
def transform_keys(hash = NOT_GIVEN, &block)
  return to_enum(:transform_keys) if NOT_GIVEN.equal?(hash) && !block_given?
  dup.tap { |h| h.transform_keys!(hash, &block) }
end

transform_keys!(hash = NOT_GIVEN, &block)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 349
def transform_keys!(hash = NOT_GIVEN, &block)
  return to_enum(:transform_keys!) if NOT_GIVEN.equal?(hash) && !block_given?

  if hash.nil?
    super
  elsif NOT_GIVEN.equal?(hash)
    keys.each { |key| self[yield(key)] = delete(key) }
  elsif block_given?
    keys.each { |key| self[hash[key] || yield(key)] = delete(key) }
  else
    keys.each { |key| self[hash[key] || key] = delete(key) }
  end

  self
end

transform_values(&block)

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 337
def transform_values(&block)
  return to_enum(:transform_values) unless block_given?
  dup.tap { |hash| hash.transform_values!(&block) }
end

update(*other_hashes, &block)

就地更新接收器,合并作为参数传递的哈希

hash_1 = ActiveSupport::HashWithIndifferentAccess.new
hash_1[:key] = 'value'

hash_2 = ActiveSupport::HashWithIndifferentAccess.new
hash_2[:key] = 'New Value!'

hash_1.update(hash_2) # => {"key"=>"New Value!"}

hash = ActiveSupport::HashWithIndifferentAccess.new
hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }

参数可以是 ActiveSupport::HashWithIndifferentAccess 或常规 Hash。在这两种情况下,合并都遵循无差别访问的语义。

如果参数是具有键 :key"key" 的常规哈希,则只有一个值最终出现在接收器中,但哪一个值是未指定的。

当给定一个块时,重复键的值将由使用重复键、接收器中的值和 other_hash 中的值调用该块的结果来确定。重复键的规则遵循无差别访问的语义

hash_1[:key] = 10
hash_2['key'] = 12
hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
还别名为:regular_updatemerge!
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 132
def update(*other_hashes, &block)
  if other_hashes.size == 1
    update_with_single_argument(other_hashes.first, block)
  else
    other_hashes.each do |other_hash|
      update_with_single_argument(other_hash, block)
    end
  end
  self
end

values_at(*keys)

返回指定索引处的值的数组

hash = ActiveSupport::HashWithIndifferentAccess.new
hash[:a] = 'x'
hash[:b] = 'y'
hash.values_at('a', 'b') # => ["x", "y"]
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 237
def values_at(*keys)
  keys.map! { |key| convert_key(key) }
  super
end

with_defaults(other_hash)

别名:reverse_merge

with_defaults!(other_hash)

别名:reverse_merge!

with_indifferent_access()

# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 62
def with_indifferent_access
  dup
end

without(*keys)

别名:except