Hash#slice(*keys) returns a new hash with only the given keys. #slice! replaces the hash with only the given keys. Works with HashWithIndifferentAccess also.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5726 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jeremy Kemper
2006-12-17 00:49:41 +00:00
parent 05a5209f82
commit 86deb27095
4 changed files with 63 additions and 5 deletions

View File

@@ -1,5 +1,7 @@
*SVN*
* Hash#slice(*keys) returns a new hash with only the given keys. #slice! replaces the hash with only the given keys. Works with HashWithIndifferentAccess also. [Jeremy Kemper]
* HashWithIndifferentAccess#to_hash converts to a Hash with String keys and the same default value. [Jeremy Kemper]
* Fix remove_constant to correctly handle constant names of the form "::A::...". References #6720. [Nicholas Seckar]

View File

@@ -1,8 +1,6 @@
require File.dirname(__FILE__) + '/hash/keys'
require File.dirname(__FILE__) + '/hash/indifferent_access'
require File.dirname(__FILE__) + '/hash/reverse_merge'
require File.dirname(__FILE__) + '/hash/conversions'
require File.dirname(__FILE__) + '/hash/diff'
%w(keys indifferent_access reverse_merge conversions diff slice).each do |ext|
require "#{File.dirname(__FILE__)}/hash/#{ext}"
end
class Hash #:nodoc:
include ActiveSupport::CoreExtensions::Hash::Keys
@@ -10,4 +8,5 @@ class Hash #:nodoc:
include ActiveSupport::CoreExtensions::Hash::ReverseMerge
include ActiveSupport::CoreExtensions::Hash::Conversions
include ActiveSupport::CoreExtensions::Hash::Diff
include ActiveSupport::CoreExtensions::Hash::Slice
end

View File

@@ -0,0 +1,28 @@
require 'set'
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module Hash #:nodoc:
# Slice a hash to include only the given keys. This is useful for
# limiting an options hash to valid keys before passing to a method:
#
# def search(criteria = {})
# assert_valid_keys(:mass, :velocity, :time)
# end
#
# search(options.slice(:mass, :velocity, :time))
module Slice
# Returns a new hash with only the given keys.
def slice(*keys)
allowed = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
reject { |key,| !allowed.include?(key) }
end
# Replaces the hash with only the given keys.
def slice!(*keys)
replace(slice(*keys))
end
end
end
end
end

View File

@@ -243,6 +243,35 @@ class HashExtTest < Test::Unit::TestCase
def test_diff
assert_equal({ :a => 2 }, { :a => 2, :b => 5 }.diff({ :a => 1, :b => 5 }))
end
def test_slice
original = { :a => 'x', :b => 'y', :c => 10 }
expected = { :a => 'x', :b => 'y' }
# Should return a new hash with only the given keys.
assert_equal expected, original.slice(:a, :b)
assert_not_equal expected, original
# Should replace the hash with only the given keys.
assert_equal expected, original.slice!(:a, :b)
assert_equal expected, original
end
def test_indifferent_slice
original = { :a => 'x', :b => 'y', :c => 10 }.with_indifferent_access
expected = { :a => 'x', :b => 'y' }.with_indifferent_access
[['a', 'b'], [:a, :b]].each do |keys|
# Should return a new hash with only the given keys.
assert_equal expected, original.slice(*keys), keys.inspect
assert_not_equal expected, original
# Should replace the hash with only the given keys.
copy = original.dup
assert_equal expected, copy.slice!(*keys)
assert_equal expected, copy
end
end
end
class IWriteMyOwnXML