Then again, I can do just fine without the map
a.split(“,”)[1…-1].join(“,”) #=> “b,c”
Still, any way to use ampersand shortcut without specifying a method to get {|a|
a} like &:foo gives {|a| a.foo }?
If the point is using ampersand, then I think it’s like Jeremy said, you
need to write your own helper method.
If the point is writing a more concise line of code, then this is one
possible way:
In Ruby (unfortunately) is no method returning an object’s identity like
`id’ function in haskell. However as you are sure about class of an
object you may cheat a bit around the missing functionality. Your
example then would look like:
a.split(’,’).drop(1).map(&:to_s)
^^^^^^^^^^^
Here ‘String#to_s’ would serve as a missing generic ‘Object.id’. For an
array of integers it would be ‘Fixnum#to_i’, for symbols ‘Symbol#to_sym’
etc.
Recollection of the same elements however makes no sense in this case.
I find this very confusing, and am not sure at all what you’re asking.
But here’s my attempt at an answer.
How is .map {|v| v} not the same as just .map() ? Array#map with no
block will return an enumerator which should work fine. I’ve seen
Array#cycle used often in this manner to get the enumerator. Why do
you even need .map in there => a.split(";")[1…-1].join(",")?
But say I want to cut off the first value of a comma-separated line:
a = “a,b,c”
a.split(";")[1…-1].map {|v| v}.join(";") #=> “b;c”
I can think of 10 ways of doing that that don’t look half as
complicated. Seems like 1-line solution obsession to me.
Regex? a.gsub!(/^\w+,/ , ‘’ )
Array#shift() ? Would be longer, but the intent is much clearer than
a.split(",")[1…-1]
Also BTW a.split(",")[1…-1] will return nil if ‘a’ is an empty
string. So any method calls after that will crash.
Just my 2 cents. But again, maybe I’m totally missing the issue.
I prefer to follow duck typing rules when it comes to such things. If
a.split().cycle().map().join() returns me the result I need, then I
don’t care if the object is an explicit array, an Enumerator, a Set or
any other random object.
Thanks to all responders. An enumerator really was not needed in my
example
(coworkers started me down that wrong path).
I ended up using a.split(“,”).shift for clarity.
On Mon, Nov 24, 2014 at 4:12 PM, Augusts B. [email protected]
wrote:
Thanks to all responders. An enumerator really was not needed in my example
(coworkers started me down that wrong path).
I ended up using a.split(“,”).shift for clarity.
Why are you making it so complicated for yourself?
irb(main):005:0> a = “a,b,c”
=> “a,b,c”
irb(main):006:0> a.sub! /^[^,]*,/, ‘’
=> “b,c”
irb(main):007:0> a
=> “b,c”
I usually get the same response Robert. I see both sides. I love
regexp
for it’s surgical precision. And once you get comfortable with the
syntax,
indeed why not just do the extraction in one step?
But in practice I find that when I use regular expressions, then I have
to
maintain that code because the developers around me prefer not to use
this
power tool. So I’d probably pick Agustus’ solution too.
I just posted a similar answer in response to another thread, but on
this one I’m with Robert. Regex can present maintenance roadblocks
when they become numerous and multi-line long; but the string parsing
problem presented here is relatively simple and a textbook example of
when you SHOULD use a regex.
Robert’s approach has two key advantages. It is more efficient in terms
of
processing and memory use. If the strings were very long and there was a
large number of them, the use of sub! avoids making copies and that
regex
does not need to process the whole line. The combo will save on time and
memory.
The only downside I see is it’s not quickly readable. You have to stop
for
a couple of seconds more to parse it in your head.
Depending on the application, and maybe the ‘audience’, it could be a
worthwhile tradeoff. Not simply ‘wrong’.
Several functional languages define an identity function (usually called id, such that id(x) = x) for this exact purpose (i.e. passing it into
contexts where a function is needed, but you don’t really want to do
anything to x). As other people have pointed out, you don’t need it
here,
since map itself defaults to doing nothing if you don’t pass it a
function,
but in general it does sometimes help with readability to define id and
then use it in your code, even if the definition adds a few more lines
of
code to your program.
About having an ampersand-colon version of the { |x| x } block, it seems https://bugs.ruby-lang.org/issues/6373 that it will be available in
vanilla Ruby when 2.2 lands: