From: shevegen@... Date: 2016-10-06T21:14:24+00:00 Subject: [ruby-core:77507] [Ruby trunk Feature#12817] Consider adding method .sample() on class Hash (if this was not yet proposed) Issue #12817 has been reported by Robert A. Heiler. ---------------------------------------- Feature #12817: Consider adding method .sample() on class Hash (if this was not yet proposed) https://bugs.ruby-lang.org/issues/12817 * Author: Robert A. Heiler * Status: Open * Priority: Normal * Assignee: ---------------------------------------- Hello ruby core team and all who may read this. Some time ago, I think in ruby 1.8.x, the method .sample() was added to class Array. I think before this addition, it was a bit more cumbersome to get a random entry from an array - I remember having used .shuffle.first or something like that, until I noticed that .sample() existed. (I do not remember if the first 1.8.x release that I used had it; I started with ruby in perhaps late 2003 or 2004 or so). Anyway. This method is very nice for class Array if we want one or more random entries. So today I wondered why class Hash does not have a sample method. Are the use cases so different to class Array? The method .sample() on class Array will return a random element, right? Well, hashes also have elements, key-value settings. So my proposal is to add either or all of these methods to class Hash: hash.sample In order to illustrate what this should do, here is pseudo-code: hash = { cat: 'Tom', mouse: 'Jerry' } hash.sample # => 'Tom' (Sorry, I loved Tom and Jerry when I was a kid so I use this as my main Hash a lot.) Note that in the above Hash, you could also create a new sub-hash such as: hash = { cat: 'Tom', mouse: 'Jerry' } hash.sample # => { :cat => 'Tom' } I don't mind either way, both is fine by me. The "will return a hash" is probably more consistent because class Array .sample() method will return an Array. So I guess that is the better variant. The main thing for me is that a method .sample could be used on class Hash, similar to class Array. If it looks like a duck and quacks like a duck ... it may be a cat pretending to be a duck! Or it may be a duck indeed. But both are animals anyway. Admittedly the above .sample() for hash is sort of more a method like .random() - that is, we return a random element. But this is how class Array's sample() already works too, right? Here is the documentation: https://ruby-doc.org/core-2.2.0/Array.html#method-i-sample The documentation for .sample() states: "Choose a random element or n random elements from the array." So you could also actually name it .random perhaps but maybe .sample() was a better name, I have no idea myself. It probably is now established and used by ruby hackers so we can stick to .sample() anyway. That documentation also has an example, which I translated or simplified a bit: array = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] array.sample # => 7 array.sample(2) # => [6, 5] I assume that for the most similar behaviour, I should picture something like this, also returning a "smaller" random representation of the given Hash: hash = { cat: 'Tom', mouse: 'Jerry', duck: 'Timmy', horse: 'Pete' } hash.sample(2) # => { duck: 'Timmy', horse: 'Pete' } hash.sample(2) # => { cat: 'Tom', horse: 'Pete' } (I guess hash.random(2) and array.random(2) might also be used to illustrate the concept, but it should be the same name to avoid confusion; since class Array already has .sample(), I would like to suggest this for class Hash). Do note that the above is already easily possible - just obtain all keys from hash, then apply .sample(), then query the hash itself again to return a hash. Example again showing only 2 sample results: hash = { cat: 'Tom', mouse: 'Jerry', duck: 'Timmy', horse: 'Pete' } keys = hash.keys sample = keys.sample(2) # => [:duck, :cat] values = hash.values_at(*sample) # => ["Timmy", "Tom"] Hash[*sample.zip(values).flatten] # => {:duck=>"Timmy", :cat=>"Tom"} So this is already possible but a bit cumbersome in my opinion. With a .sample() method this would be easier to use and re-use. No idea if this is a good suggestion or something that can not be added for any reason but I wanted to propose it at the least, in the event that nobody else has done so. If it was already proposed before, sorry for not finding it; feel free to link it into the other proposal and close the request here in that latter case. Thank you for reading - may ruby save many more ducks in the future. -- https://bugs.ruby-lang.org/ Unsubscribe: