Project

General

Profile

Actions

Feature #13563

closed

Implement Hash#choice method.

Added by babanba-n (matzbara masanao) over 7 years ago. Updated almost 7 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-dev:50114]

Description

Hi,

I propose Hash#choice method.

It pick up key and value pairs in Hash like a below code.

{ :a => 1, 2 => "2", "c" => true }.choice(:a, 2) # => { :a => 1, 2 => "2" }
{ :a => 1, 2 => "2", "c" => true }.choice("c", 10000) # => { "c" => true, 10000 => nil }

This method is useful when Hash have many keys, but programer need few key's.

For instance, it pick up personal data in ActiveRecord model's data, and migrate to new device.

feature_phone_user = User.find(params[:src_user_id])
profile = feature_phone_user.attributes.choice(*%i[nickname email sex birthday prefecture])
smart_phone_user   = User.new
smart_phone_user.attributes = profile

In other case, it pick up latest log from http request parameter.

condition = params.to_h.choice("user_id", "service_id")
latest_payment_log = PaymentLog.find_by(condition).last

If this method exist, I guess that many cases change to comfortable just a little.

Please consider about it.

And I write it.
https://github.com/baban/ruby/commit/4014ebe2ae261881669bef8369eb08aaecef2034


Related issues 2 (0 open2 closed)

Related to Ruby master - Feature #8499: Importing Hash#slice, Hash#slice!, Hash#except, and Hash#except! from ActiveSupportClosedmatz (Yukihiro Matsumoto)Actions
Related to Ruby master - Feature #15822: Add Hash#exceptClosedActions
Actions #1

Updated by babanba-n (matzbara masanao) over 7 years ago

  • Subject changed from Implement Hash#choice mtthod. to Implement Hash#choice method.

Updated by shevegen (Robert A. Heiler) over 7 years ago

I am neutral about the suggestion, neither pro or con.

I think the only thing that I want to point out is that .choice() is perhaps not
completely clear. Perhaps .pick() would be better?

We have quite some methods already that allow us to .select() .reject(); and
it also reminds me a bit about .shuffle() and .sample().

I guess this is not the fault of anyone by the way, we just do not have that
many (one-word) english words that are for verbs/actions. So perhaps .choice()
is a good name anyway.

Updated by matthewd (Matthew Draper) over 7 years ago

FWIW, ActiveSupport calls this Hash#slice -- http://api.rubyonrails.org/classes/Hash.html#method-i-slice

(With one small behavioural difference: keys not present in the source hash are also omitted from the result, so the second example would return { "c" => true }, not { "c" => true, 10000 => nil }.)

Updated by babanba-n (matzbara masanao) over 7 years ago

At first, I overlook Hash#slice method. Sorry...
And, I reconsider about it.

I feel that Hash#slice is wrong name and Hash#pick is better name.
If key is not exist, key omit or return nil.
It is difficult problem.

I think each way have usecase.

For example, below code is return first row.

Item = ItemStock.find_by({}) # return first row 

For that reason, below code have possibility return unintended data.

item = ItemStock.find_by(params.to_h.slice("user_id","item_id")) 
return render { result: "NG" } if item.amount.zero?
item.consume 
render json: { result: "OK" }

So returning nil is more safety.

Updated by saturnflyer (Jim Gay) over 7 years ago

babanba-n (matzbara masanao) wrote:

I feel that Hash#slice is wrong name and Hash#pick is better name.
If key is not exist, key omit or return nil.
It is difficult problem.

I prefer Hash#pick over Hash#choice.

I would expect the missing keys to return whatever the default value of the hash is.

hash = Hash.new('foo')
hash[:bar] = 'hello world'

hash.pick(:baz, :bar) #=> {:baz => 'foo', :bar => 'hello world' }

Updated by babanba-n (matzbara masanao) over 7 years ago

Thanks reply, saturnflyer.
And I totally agree your propose.

Even if, this porpose is rejected.
I will fix code, and re-push it.

Updated by Hanmac (Hans Mackowiak) over 7 years ago

babanba-n (matzbara masanao) wrote:

And, I fix to Hash#pick.

https://github.com/baban/ruby/commit/fa9d1d6291e4507c5fdd997c269cd1cd68003899

in the test case, shouldn't the @h.default= "default" be before the pick?

Actions #10

Updated by mrkn (Kenta Murata) about 7 years ago

  • Related to Feature #8499: Importing Hash#slice, Hash#slice!, Hash#except, and Hash#except! from ActiveSupport added

Updated by matz (Yukihiro Matsumoto) about 7 years ago

I vote for Hash#slice that is ActiveSupport compatible.

Matz.

Actions #12

Updated by marcandre (Marc-Andre Lafortune) almost 7 years ago

  • Status changed from Open to Closed
Actions #13

Updated by matz (Yukihiro Matsumoto) about 5 years ago

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0