Method: Immutable::Vector#update_in

Defined in:
lib/immutable/vector.rb

#update_in(*key_path) {|value| ... } ⇒ Vector

Return a new Vector with a deeply nested value modified to the result of the given code block. When traversing the nested ‘Vector`s and `Hash`es, non-existing keys are created with empty Hash values.

The code block receives the existing value of the deeply nested key (or nil if it doesn’t exist). This is useful for “transforming” the value associated with a certain key.

Note that the original Vector and sub-‘Vector`s and sub-`Hash`es are left unmodified; new data structure copies are created along the path wherever needed.

Examples:

v = Immutable::Vector[123, 456, 789, Immutable::Hash["a" => Immutable::Vector[5, 6, 7]]]
v.update_in(3, "a", 1) { |value| value + 9 }
# => Immutable::Vector[123, 456, 789, Immutable::Hash["a" => Immutable::Vector[5, 15, 7]]]

Parameters:

  • key_path (Object(s))

    List of keys which form the path to the key to be modified

Yields:

  • (value)

    The previously stored value

Yield Returns:

  • (Object)

    The new value to store

Returns:



198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/immutable/vector.rb', line 198

def update_in(*key_path, &block)
  if key_path.empty?
    raise ArgumentError, "must have at least one key in path"
  end
  key = key_path[0]
  if key_path.size == 1
    new_value = block.call(get(key))
  else
    value = fetch(key, Immutable::EmptyHash)
    new_value = value.update_in(*key_path[1..-1], &block)
  end
  set(key, new_value)
end