Feature #13563
closedImplement Hash#choice method.
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
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 babanba-n (matzbara masanao) over 7 years ago
And, I fix to Hash#pick.
https://github.com/baban/ruby/commit/fa9d1d6291e4507c5fdd997c269cd1cd68003899
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?
Updated by babanba-n (matzbara masanao) over 7 years ago
Sorry,I'm so embarrassed.
https://github.com/baban/ruby/commit/b3b7f5f701e9bfbbc946d27d3397adc1c99125f6
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.
Updated by marcandre (Marc-Andre Lafortune) almost 7 years ago
- Status changed from Open to Closed
Updated by matz (Yukihiro Matsumoto) about 5 years ago
- Related to Feature #15822: Add Hash#except added