This question already has an answer here:
How can I more elegantly remove duplicate items across all elements of a Ruby Array?
(1 answer)
Closed 8 years ago.
I have this piece of code in an application and was told to make it more elegant but have no idea how to make it better
self.join(" ").split(" ").uniq
Any suggestion will be much appreciated.
self is an array
flat_map(&:split).uniq
flat_map runs a block over an array, and concatenates all the resulting arrays.
flat_map(&:split) is equivalent to calling s.split on every argument, which happens to do the exact same thing as s.split(' '), (unless you redefine $;, but please don't do that).
We don't need self, so we omit it.
Related
This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 4 years ago.
I've seen an example of how to sort a string. To sort case insensitively:
str.chars.sort(&:casecmp).join
#=> "ginrSt"
I'm curious about (&:casecmp). I found that for example:
arr.map(&:name)
is shorthand for
arr.map(&:name.to_proc)
which is same with
arr.map{|el| el.name}
I know the & (ampersand) tries to convert symbol to proc, and pass it as a block to a method. I do not understand how this would work for sort method, which is supposed to compare two values. Would it be as follows?
str.chars.sort{|a, b| a.casecmp ;b.casecmp}.join
It wouldn't be helpful since soft needs a block to return an integer and casecmp needs an argument. (Or is it called parameter in that case?) To me, it looks more like this:
str.chars.sort{|a, b| a.casecmp(b)}.join
How does &:casecmp know to take one of |a, b| as a caller and the other one as an argument? I wouldn't guess it that it is an option.
If more than one parameter is passed to your block, the proc created by Symbol#to_proc uses the additional block parameters as parameters to the method call.
http://phrogz.net/symbol-to-proc-with-multiple-arguments
So, what's really happening is, sort(&:casecmp) is converted to:
sort {|a,b| a.casecmp(b) }
because sort takes two parameters.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
What do you call the &: operator in Ruby?
I see '.map(&:chomp)' all the time
I know what chomp and map do, but I want to know what &: does and I'd like to know why I can't find it on the web after 30 minutes of googling.....
It's Symbol#to_proc, and it turns the symbol into a proc which attempts to invoke the given method on its argument, returning the result.
x = :reverse.to_proc
x.call("asdf") # "fdsa", like calling "asdf".reverse
In your case, .map(&:chomp) is equivalent to .map { |x| x.chomp }.
If you can't find it by Googling, it's because you're Googling the wrong thing. It's a well-known Ruby idiom.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a reason that we cannot iterate on “reverse Range” in ruby?
This works like magic.
for i in 1..10
...
end
Isn't it only intuitive that this backward for loop should work as well?
for i in 10..1
...
end
If there is some syntactical reason why this shouldn't work, I feel like ruby has to be changed to allow it. It's just intuitive to write backward for loop that way.
try something like
10.downto(1) { |i| ... }
1..10 is of class Range, not directly linked with any loop constructs. And there are no numbers that are both bigger than 10 and smaller than 1, therefore the range 10..1 is empty.
PS I don't recall when was the last time I wrote a for loop in ruby. Maybe something from http://www.ruby-doc.org/core-1.9.2/Enumerable.html would serve you better?
This question already has an answer here:
naked asterisk as parameter in method definition: def f(*)
(1 answer)
Closed 10 years ago.
I was poking through the Rails 3 ActiveRecord source code today and found a method where the entire parameter list was a single asterisk.
def save(*)
I couldn't find a good description of what this does (though I have some ideas based on what I know about splat arguments).
What does it do, and why would you use it?
It means it can have any number of arguments (including zero) and it discards all those arguments.
This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 8 years ago.
I saw the code from here
Post.published.collect(&:views_count)
I guess it equals to
.collect { |p| p.views_count }
But I never saw this usage before, does this have a name? Where can I find more information about it?
This is actually a rather clever hack made it into ruby 1.9.
Basically, & in front of a variable in ruby coerces it into a proc. It does that by calling to_proc. Some clever fellow (first time I saw this was in _whys code, but I won't credit him cause I don't know if he came up with it) added a to_proc method to Symbol, that is essentially {|obj| obj.send self}.
There aren't many coercians in ruby, but it seems like all of them are mostly used to do hacks like this (like !! to coerce any type into a boolean)
It's a use of Symbol#to_proc. The & operator turns a Proc object into a block, and because Ruby 1.8.7 and newer implement Symbol#to_proc, it can be used with a symbol like :views_count. And yes, it's equivalent to {|p| p.views_count}.