Project

General

Profile

Actions

Misc #18352

open

What is the Hash#grep expected?

Added by zw963 (Wei Zheng) 11 months ago. Updated 10 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
[ruby-core:106188]

Description

Current ruby implement, When use Array#grep, the method name means is expected.

[19] pry(#<App>)> [:foo1, :foo2, :bar].grep /foo/                                                                                                                                             
[
    :foo1,
    :foo2
]

But when use with hash, the result is really confusing ...

[12] pry(#<App>)> {foo: '100', bar: '200'}.grep /foo/                                                                                                                                         
[]

This result almost make Include Enumerable#grep into Hash is totally meaningless, right?

so, i consider if we should introduce a Hash#grep method instead.

Following is what is expected. (=== is matching on hash key, as Hash#slice)

[20] pry(#<App>)> {foo1: '100', foo2: '200', bar: '200'}.grep /foo/                                                                                                                
{
    :foo1 => "100",
    :foo2 => "200"
}

Updated by zverok (Victor Shepelev) 11 months ago

This result almost make Include Enumerable#grep into Hash is totally meaningless, right?

Not completely, but close to it :) As grep accepts anything with #===, we might imagine some custom useful objects passed, like, IDK....

class HashMatcher < Struct.new(:key, :value, keyword_init: true)
  def ===((k, v))
    (key.nil? || key === k) && (value.nil? || value === v)
  end
end

{foo1: '100', foo2: '200', bar: '200'}.grep(HashMatcher[key: /foo/])
# => [[:foo1, "100"], [:foo2, "200"]]

...but that would be quite an esoteric technique (which I personally never used)

But, considering more useful Hash#grep, I am not sure I agree with this:

Following is what is expected. (=== is matching on hash key, as Hash#slice)

Why not match only hash value, like, say, Hash#compact?

{foo1: '100', foo2: '200', bar: '200'}.grep /^1/
# => {foo1: '100'}

{foo1: 100, foo2: 200, bar: 200}.grep(100...150)
# => {foo1: '100'}

I can imagine arguments towards both behaviors saying that they are "natural/useful/expected", and I don't think there is one right answer here actually.

Updated by matheusrich (Matheus Richard) 10 months ago

Should we have grep_{keys,values}?

Actions

Also available in: Atom PDF