Even shorter Ampersand to_proc?

So these are equivalent:

something {|i| i.foo }
something(&:foo)

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”

Can I somehow use ampersand (or to_proc) to have a shorthand of {|v| v}
Any way to use something like this?

a.split(";")[1…-1].map&join(";")

Thanks,

Augusts B.

Creative Mobile

There’s a bug in your code and the map function is just creating a copy
of your array, i don’t think that’s your intended goal.

About your last example, you wanna call join on the array, not use join
in the block for map.

Let us/me know if you have any questions.

Sent from my phone.

Messed up the code adapting it to example. This should work:

a = “a,b,c”
a.split(“,”)[1…-1].map {|v| v}.join(“,”) #=> “b,c”

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 }?

On Sat, Nov 22, 2014 at 11:32 AM, Jeremy Axelrod
[email protected]
wrote:

a = “a,b,c”

Creative Mobile

Augusts B.

Creative MobileKronvalda bulvaris 10, Riga**office: 00371 67227747
mobile: 00371 29957771
www.creo.mobi http://www.creo.mobi/

On Nov 22, 2014, at 11:39 AM, Augusts B. [email protected] wrote:

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:

a.split(‘,’, 2).last

Regards,
Ammar

I think it’s only possible if you write you’re own helper function.
That’s not very optimal.

A simpler solution would be to directly manipulate the ‘a’ var. Not
using the ampersand.

Jeremy

Sent from my phone

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 5:05 PM, bruka [email protected] wrote:

a = “a,b,c”

a = “a,b,c”
Creative Mobile

Augusts B.

Creative MobileKronvalda bulvaris 10, Riga**office: 00371 67227747
mobile: 00371 29957771
www.creo.mobi http://www.creo.mobi/

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”

Cheers

robert

On Mon, Nov 24, 2014 at 5:58 PM, Brandon W.
[email protected] wrote:

There are times when regex is wrong. This is such a time.

Why?

There are times when regex is wrong. This is such a time.

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.

On Mon, Nov 24, 2014 at 6:49 PM, Robert K.
[email protected]

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.

Best tool for the job and all that.

Why is regex wrong?

Sent from my phone

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’.

On Mon, Nov 24, 2014 at 6:58 PM, Brandon W.
[email protected]

If you want readable you can refactor into a constant with a good name

EVERYTHING_UP_TO_A_COMMA=/…/

Then the code becomes

a.sub! EVERYTHING_UP_TO_A_COMMA, ‘’

Jesus.
El 24/11/2014 19:59, “Ammar A.” [email protected] escribió:

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.

martin

Augusts B. wrote in post #1163083:

Can I somehow use ampersand (or to_proc) to have a shorthand of {|v| v}

define a method in Object class:
class Object ; def myself() self end end

and then use it in your map :
[1,2,3].map(&:myself)

which is equivalent to clone the list:
[1,2,3].clone

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:

[1,2,3,4,5,1,2,2,3].group_by(&:itself)
#=> {1=>[1, 1], 2=>[2, 2, 2], 3=>[3, 3], 4=>[4], 5=>[5]}

On Mon, Nov 24, 2014 at 7:52 PM, Martin DeMello
[email protected]