Feature #8499
closedImporting Hash#slice, Hash#slice!, Hash#except, and Hash#except! from ActiveSupport
Description
According to my experiences, the following two idioms often appeare in application codes.
hash = other_hash.select { |k, | [:key1, :key2, :key3].include? k }
hash = other_hash.reject { |k, | [:key1, :key2, :key3].include? k }
On Rails, they can be written in the following forms by using ActiveSupport's features.
hash = other_hash.slice(:key1, :key2, :key3)
hash = other_hash.except(:key1, :key2, :key3)
I think the latter forms are shorter and more readable than the former ones.
So I propose to import the following methods from ActiveSupport:
Hash#slice
Hash#slice!
Hash#except
Hash#except!
Files
Updated by zzak (zzak _) over 11 years ago
Hello,
On Thu, Jun 6, 2013 at 4:12 PM, mrkn (Kenta Murata) muraken@gmail.com wrote:
On Rails, they can be written in the following forms by using ActiveSupport's features.
hash = other_hash.slice(:key1, :key2, :key3)
hash = other_hash.reject(:key1, :key2, :key3}
Do you mean "other_hash.except(...)
"? There is already Hash#reject
Updated by nobu (Nobuyoshi Nakada) over 11 years ago
- Description updated (diff)
Updated by mrkn (Kenta Murata) over 11 years ago
zzak (Zachary Scott) wrote:
Hello,
On Thu, Jun 6, 2013 at 4:12 PM, mrkn (Kenta Murata) muraken@gmail.com wrote:
On Rails, they can be written in the following forms by using ActiveSupport's features.
hash = other_hash.slice(:key1, :key2, :key3)
hash = other_hash.reject(:key1, :key2, :key3}
Do you mean "
other_hash.except(...)
"? There is alreadyHash#reject
Yes, It's my mistake!
How can I edit the issue description?
Updated by mrkn (Kenta Murata) over 11 years ago
- Description updated (diff)
I could fix the description.
Updated by nobu (Nobuyoshi Nakada) over 11 years ago
Or enhance the existing methods?
Updated by mrkn (Kenta Murata) over 11 years ago
nobu (Nobuyoshi Nakada) wrote:
Or enhance the existing methods?
I think Hash#[]
with the multiple arguments can be an alternative of Hash#slice
.
Updated by nobu (Nobuyoshi Nakada) over 11 years ago
mrkn (Kenta Murata) wrote:
I think
Hash#[]
with the multiple arguments can be an alternative ofHash#slice
.
Hash#[]
should return the values, not the pairs.
Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 11 years ago
+1
Updated by prijutme4ty (Ilya Vorontsov) over 11 years ago
mrkn (Kenta Murata) wrote:
nobu (Nobuyoshi Nakada) wrote:
Or enhance the existing methods?
I think
Hash#[]
with the multiple arguments can be an alternative ofHash#slice
.
There was a proposal (can't find it) to make indexing by multiple arguments to work as nested hashes so that hsh[:a,:b,:c]
works as (hsh[:a] && hsh[:a][:b] && hsh[:a][:b][:c])
. Your proposal automatically blocks this proposal.
Updated by mrkn (Kenta Murata) over 11 years ago
prijutme4ty (Ilya Vorontsov) wrote:
mrkn (Kenta Murata) wrote:
nobu (Nobuyoshi Nakada) wrote:
Or enhance the existing methods?
I think Hash#[] with the multiple arguments can be an alternative of Hash#slice.
There was a proposal (can't find it) to make indexing by multiple arguments to work as nested hashes so that hsh[:a,:b,:c] works as (hsh[:a] && hsh[:a][:b] && hsh[:a][:b][:c]). Your proposal automatically blocks this proposal.
My proposal primaliry consists of Hash#slice, Hash#except, and bang versions of them.
Hash#[] is optional.
Updated by claytrump (Clay Trump) over 11 years ago
Yay, +1 for slice
& except
BTW, makes no sense to me if h[:foo, :bar]
returns keys and values in a
hash while h[:foo]
returns a value.
<lay trum/>
Updated by mrkn (Kenta Murata) over 11 years ago
On Fri, Jun 7, 2013 at 1:50 AM, Zachary Scott zachary@zacharyscott.net wrote:
Please update description if the proposal has changed (ie:
Hash#[]
)
I mentioned Hash#[]
as the reply to nobu's comment #6.
It has not changed my proposal.
My proposal only consists of slice
, slice!
, except
, and except!
.
--
Kenta Murata
OpenPGP FP = 1D69 ADDE 081C 9CC2 2E54 98C1 CEFE 8AFB 6081 B062
Updated by nobu (Nobuyoshi Nakada) over 11 years ago
I meant Hash#select
and Hash#reject
by "the existing methods".
i.e.:
hash = other_hash.select(:key1, :key2, :key3)
hash = other_hash.reject(:key1, :key2, :key3)
But Hash#slice
and Hash#except
seems fine.
Updated by Glass_saga (Masaki Matsushita) over 11 years ago
- File patch.diff patch.diff added
How about this implementation?
Updated by matz (Yukihiro Matsumoto) over 11 years ago
The slice method (Array#slice
) retrieve "a slice of elements" from an Array
.
Considering that, slice is not a good name for the behavior.
So, I prefer Nobu's idea in comment #16
hash = other_hash.select(:key1, :key2, :key3)
hash = other_hash.reject(:key1, :key2, :key3)
Matz
Updated by znz (Kazuhiro NISHIYAMA) over 11 years ago
In attached patch.diff
assert_equal({1=>2, 3=>4}, h.slice!(1, 3))
but ActiveSupport's h.slice!(1, 3)
returns {5=>6}
.
http://api.rubyonrails.org/classes/Hash.html#method-i-slice-21
Updated by nobu (Nobuyoshi Nakada) over 11 years ago
I've missed the returned values until I've implemented it actually.
-
In ActiveSupport
-
Hash#slice!
keeps the given keys and returns removed key/value pairs. -
Hash#except!
removes the given keys and returns self.
-
-
In this proposal
-
Hash#slice!
removes the given keys and returns removed key/value pairs. -
Hash#except!
is same as ActiveSupport.
-
-
Existing methods
-
Hash#select!
keeps the given (by the block) keys and returns self ornil
. -
Hash#reject!
removes the given (by the block) keys and returns self ornil
.
-
I don't think changing the result semantics by if any arguments are given is good idea.
What I've thoutht about Hash#slice!
was Hash#extract!
in ActiveSupport actually.
So what about Hash#extract
, Hash#except
and those !
-versions?
Updated by mrkn (Kenta Murata) over 11 years ago
The attached file is not a part of my proposal. It made by Glass_saga. My proposal is the same as ActiveSupport.
Updated by Glass_saga (Masaki Matsushita) over 11 years ago
- File patch2.diff patch2.diff added
I'm sorry for my wrong implementation.
patch2.diff makes Hash#slice!
and #except!
behave the same as ActiveSupport.
However, I think it isn't good idea to import Hash#slice!
and #except!
from ActiveSupport as it is.
Because:
- They returns self if no changes were made. It is inconsistent with other built-in methods like
#select!
and#reject!
. -
#slice!
returns rest of hash, not slice of hash like following. It may be confusing.
hash = {1=>2,3=>4,5=>6}
hash.slice!(1,3) #=> {5,6}
hash #=> {1=>2,3=>4}
Updated by hsbt (Hiroshi SHIBATA) almost 11 years ago
- Target version changed from 2.1.0 to 2.2.0
Updated by nobu (Nobuyoshi Nakada) over 10 years ago
- Description updated (diff)
Another name, Hash#only
.
http://blog.s21g.com/articles/228
Updated by ko1 (Koichi Sasada) over 9 years ago
- Related to Feature #9108: Hash sub-selections added
Updated by keithrbennett (Keith Bennett) almost 9 years ago
I was about to report this feature request but was happy to find that it was already there...but disappointed that it's been here so long. I'm using Ruby but not Rails and have been needing this functionality a lot lately.
Unless I'm misunderstanding, the implementation of such methods would be trivial. I would much rather see this implemented with a nonoptimal name than not implemented at all.
'slice' and 'except' are ok with me, but if there is a concern about their correctness as names, perhaps they could be 'select_if_key_in' and 'reject_if_key_in'.
But again, anything would be better than nothing.
Updated by shyouhei (Shyouhei Urabe) over 8 years ago
- Related to Feature #12461: Hash & keys to make subset. added
Updated by mrkn (Kenta Murata) about 7 years ago
- Related to Feature #13563: Implement Hash#choice method. added
Updated by Glass_saga (Masaki Matsushita) about 7 years ago
- File patch3.diff patch3.diff added
- Target version set to 2.5
I just rebased it to trunk.
Updated by Glass_saga (Masaki Matsushita) about 7 years ago
- File patch4.diff patch4.diff added
Improved implementation and test.
Added documentation.
Updated by knu (Akinori MUSHA) about 7 years ago
One concern is that Array#slice! returns deleted elements whereas this Hash#slice! would return pairs left after slicing.
Updated by mrkn (Kenta Murata) about 7 years ago
- Status changed from Assigned to Closed
As Hash#slice
has been accepted in #13563, I decided to close this issue.
I intend to open the different issue for discussing other methods such as Hash#except
.
Thanks.
Updated by nobu (Nobuyoshi Nakada) over 5 years ago
- Has duplicate Feature #15822: Add Hash#except added
Updated by nobu (Nobuyoshi Nakada) over 5 years ago
- Related to Feature #15863: Add `Hash#slice!` and `ENV.slice!` added