Split the string

S

Sijo Kg

I have a string
@selected_related_model_id_assotype_and_name=params[:relatedidmodelasso]

This is of the form
3:43;SD,2:65;SD,3:50;Inc

How can i split this to get

=>[["3","43","SD"],["2","65","SD"],["3","50","Inc"]]

Sijo
 
C

Christopher Swasey

I have a string
@selected_related_model_id_assotype_and_name=params[:relatedidmodelasso]

This is of the form
3:43;SD,2:65;SD,3:50;Inc

How can i split this to get

=>[["3","43","SD"],["2","65","SD"],["3","50","Inc"]]

Sijo

First split by the comma, then #map the result and split using a conditional:

"3:43;SD,2:65;SD,3:50;Inc".split(/,/).map { |i| i.split(/:|;/) }
=> [["3", "43", "SD"], ["2", "65", "SD"], ["3", "50", "Inc"]]

Christopher
 
S

Sijo Kg

Sir

Here i have to get the first 2 fields as integer and the third as
string.Could u please tell how can i do that in the map?

Sijo
 
C

Christopher Swasey

Sir

Here i have to get the first 2 fields as integer and the third as
string.Could u please tell how can i do that in the map?

Not so elegantly.

Map doesn't come in handy here because the string would get converted
to a 0. What you can do is hold the split inside a temporary variable
and construct another array, as such:

arr = "3:43;SD,2:65;SD,3:50;Inc".split(/,/).map do |i|
t = i.split(/:|;/)
t[0..1].map { |j| j.to_i } << t[2]

### If you're using Rails you can use Symbol#to_proc to simplify the code
# t[0..1].map(&:to_i) << t[2]

### or something very simple, if a tiny bit repetitive:
# [t[0].to_i, t[1].to_i, t[2]]
end
=> [[3, 43, "SD"], [2, 65, "SD"], [3, 50, "Inc"]]

Christopher
 
S

Sijo Kg

Here what is the meaning of this

t[0..1].map(&:to_i) << t[2]

Could u please explain details what split and map does?I am beginner in
ruby and ror

Sijo
 
P

Peña, Botp

T24gQmVoYWxmIE9mIFNpam8gS2c6DQojIFRoaXMgaXMgb2YgdGhlIGZvcm0NCiMgMzo0MztTRCwy
OjY1O1NELDM6NTA7SW5jDQojIEhvdyBjYW4gaSBzcGxpdCB0aGlzIHRvIGdldA0KIyA9PltbIjMi
LCI0MyIsIlNEIl0sWyIyIiwiNjUiLCJTRCJdLFsiMyIsIjUwIiwiSW5jIl1dDQojLi4uDQojIEhl
cmUgaSBoYXZlIHRvIGdldCB0aGUgZmlyc3QgMiBmaWVsZHMgYXMgaW50ZWdlciBhbmQgdGhlIHRo
aXJkIGFzIA0KIyBzdHJpbmcNCg0KcmVhZCBvbiBzcGxpdCwgYXJyYXlzLCBhbmQgZW51bWVyYXRv
cnMuDQoNCnRoaXMgaXMganVzdCBhIHNpbXBsZSBleGFtcGxlLA0KDQppcmIobWFpbik6MDM3OjA+
IHJlcXVpcmUgJ2VudW1lcmF0b3InDQo9PiBmYWxzZQ0KDQppcmIobWFpbik6MDM4OjA+IHM9IjM6
NDM7U0QsMjo2NTtTRCwzOjUwO0luYyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ID0+ICIzOjQzO1NELDI6NjU7U0QsMzo1MDtJbmMiDQoNCmlyYihtYWluKTowMzk6MD4gYT1bXQ0K
PT4gW10NCg0KaXJiKG1haW4pOjA0MDowPiBzLnNwbGl0KC8sfDp8Oy8pLmVhY2hfc2xpY2UoMyl7
fHh8IGEgPDwgW3hbMF0udG9faSx4WzFdLnRvX2kseFsyXV19DQo9PiBuaWwNCg0KaXJiKG1haW4p
OjA0MTowPiBhDQo9PiBbWzMsIDQzLCAiU0QiXSwgWzIsIDY1LCAiU0QiXSwgWzMsIDUwLCAiSW5j
Il1dDQoNCg0Ka2luZCByZWdhcmRzIC1ib3RwDQo=
 
C

Christopher Swasey

Here what is the meaning of this


t[0..1].map(&:to_i) << t[2]


Could u please explain details what split and map does?I am beginner in
ruby and ror

The code, for reference:

arr = "3:43;SD,2:65;SD,3:50;Inc".split(/,/).map do |i|
t = i.split(/:|;/)
t[0..1].map(&:to_i) << t[2]
end

First, what we're doing here is splitting the string into an array by
the commas. This gets us
=> ["3:43;SD", "2:65;SD", "3:50;Inc"]

Then we're iterating through the resulting array using #map. #map is
provided by Enumerable. It iterates through all the elements of a
collection and combines the results into a new array.

#map passes each element to a block, one at a time. So, the first
element that gets passsed to the block is the string "3:43;SD". What's
important about the block is that the last expression to be evaluated
gets returned, and #map will add the returned value onto the array
that it's building. Inside the block we can do whatever we need to to
build the returned value.

In this case, we want the returned value to be a second array with the
individual parts of the current string split up. If it didn't matter
whether or not the resulting values were strings or integers then we
could just call #split on the string and leave it at that, as
"3:43;SD".split(/:\;/)
returns
=> ["3", "43", "SD"]
which, as the last expression evaluated, would get returned by the
block and pushed onto the array being built by #map.

You can think of #map as a function that transforms a collection, item
by item, and gives you back a new collection of the same size with the
same transformation applied to each constituent element. In this case,
we're taking an array of strings, transforming each individual string
into its own array, and we end up with an array of arrays.
=> [["3", "43", "SD"], ["2", "65", "SD"], ["3", "50", "Inc"]]

Now, in this case all we've done is split a bunch of strings, so each
ultimate element of the array is still going to be a string, even when
they appear to be numbers and we want them to be integers. Ideally,
what we'd do is a nested #map that called #to_i on each element to
convert them to integers:
i.split(/:|;/).map { |j| j.to_i }
The problem is that we want the third element to remain a string.
Calling #to_i on "SD" will return
=> 0

Which brings us to
t[0..1].map(&:to_i) << t[2]

What this does is slice out the first two elements of the array that
the #split gave us. This results in an array. In this case t[0..1]
would give us
=> ["3", "43"]

Then we're mapping that to a new array by calling to_i on each element
=> [3, 43]

Finally, we're pushing the string that we want to keep ("SD") onto the end
[3, 43] << t[2]
=> [3, 43, "SD"]

As the last expression to be evaluated, that completed array is
returned to #map and gets pushed onto the final, resulting array.

Now, I kind of skipped over a bit of code.
t[0..1].map(&:to_i) << t[2]
Specifically, the "&:to_i" part. This is somewhat advanced, and I'd
suggest that you read up on blocks and Procs ASAP. This is a good
opportunity to do so. Such knowledge is a prerequisite to
understanding Symbol#to_proc. (Symbol#to_proc, btw, isn't part of Ruby
core, it's a feature of Rails, although not exclusively).

To put it in simple terms, prepending & to a symbol results in
#to_proc being called on that symbol. #to_proc returns a simple block
which accepts an object and calls the specified method. In this case,
[].map(&:to_i)
is the equivalent of
[].map { |i| i.to_i }

Again, it's very simple and neat and efficient if you understand how
all the pieces of Ruby link together to make it possible. Once you
read up on Procs and blocks it should make sense.

Christopher
 
M

Michael Fellinger

I have a string
@selected_related_model_id_assotype_and_name=params[:relatedidmodelasso]

This is of the form
3:43;SD,2:65;SD,3:50;Inc

How can i split this to get

=>[["3","43","SD"],["2","65","SD"],["3","50","Inc"]]

require 'scanf'
"3:43;SD,2:65;SD,3:50;Inc".split(',').map do |e|
e.scanf('%d:%d;%s')
end
# [[3, 43, "SD"], [2, 65, "SD"], [3, 50, "Inc"]]

^ manveru
 
C

Christopher Swasey

I have a string
@selected_related_model_id_assotype_and_name=params[:relatedidmodelasso]

This is of the form
3:43;SD,2:65;SD,3:50;Inc

How can i split this to get

=>[["3","43","SD"],["2","65","SD"],["3","50","Inc"]]


require 'scanf'
"3:43;SD,2:65;SD,3:50;Inc".split(',').map do |e|
e.scanf('%d:%d;%s')
end
# [[3, 43, "SD"], [2, 65, "SD"], [3, 50, "Inc"]]

^ manveru

We have a winner!

Christopher
 
P

Peña, Botp

RnJvbTogUzIgW21haWx0bzpub24uc3RvLmdpb2FuZG9Abmllbi50ZV0gDQojIE1pY2hhZWwgRmVs
bGluZ2VyIHdyb3RlOg0KIyA+IHJlcXVpcmUgJ3NjYW5mJw0KIyA+ICIzOjQzO1NELDI6NjU7U0Qs
Mzo1MDtJbmMiLnNwbGl0KCcsJykubWFwIGRvIHxlfA0KIyA+ICAgZS5zY2FuZignJWQ6JWQ7JXMn
KQ0KIyA+IGVuZA0KIyA+ICMgW1szLCA0MywgIlNEIl0sIFsyLCA2NSwgIlNEIl0sIFszLCA1MCwg
IkluYyJdXQ0KIyANCiMgYnV0IGhlIHdhbnRzIGFsbCBzdHJpbmdzIGluIGhpcyBhcnJheQ0KDQpu
bywgaWYgeW91IHNjYW4gdGhlIHRocmVhZCwgdGhlIG9wIGxhdGVyIHdhbnRlZCB0aGUgZmlyc3Qg
MiBlbGVtZW50cyBiZSBpbnRlZ2Vycy4gDQoNCmtpbmQgcmVnYXJkcyAtYm90cA0K
 
P

Peña, Botp

From: Christopher Swasey [mailto:[email protected]]=20
# > require 'scanf'
# > "3:43;SD,2:65;SD,3:50;Inc".split(',').map do |e|
# > e.scanf('%d:%d;%s')
# > end
# > # [[3, 43, "SD"], [2, 65, "SD"], [3, 50, "Inc"]]
# >
# > ^ manveru
#=20
# We have a winner!
#

careful, you might want to benchmark that, too.

a sample run on a windows machine,

C:\Documents and Settings\botp>cat test.rb

require 'benchmark'
require 'enumerator'
require 'scanf'

n=3D1_000
s=3D"3:43;SD,2:65;SD,3:50;Inc"

puts RUBY_VERSION,RUBY_PLATFORM

Benchmark.bmbm do |x|
x.report("scan") do
n.times do
s.scan(/(\d+):(\d+);(\w+)/).map do |x| [x[0].to_i,x[1].to_i,x[2]] =
e
end
end
x.report("slice") do
n.times do
a=3D[]
s.split(/,|:|;/).each_slice(3){|x| a << =
[x[0].to_i,x[1].to_i,x[2]]}
end
end
x.report("split2") do
n.times do
s.split(/,/).map do |i|
t =3D i.split(/:|;/)
t[0..1].map { |j| j.to_i } << t[2]
end
end
end
x.report("scanf") do
n.times do
s.split(',').map do |e| e.scanf('%d:%d;%s') end
end
end

end


C:\Documents and Settings\pe=F1aijm>ruby test.rb
1.8.6
i386-mswin32
Rehearsal ------------------------------------------
scan 0.063000 0.000000 0.063000 ( 0.063000)
slice 0.078000 0.000000 0.078000 ( 0.079000)
split2 0.109000 0.000000 0.109000 ( 0.110000)
scanf 2.938000 0.015000 2.953000 ( 3.188000)
--------------------------------- total: 3.203000sec

user system total real
scan 0.063000 0.000000 0.063000 ( 0.063000)
slice 0.093000 0.000000 0.093000 ( 0.094000)
split2 0.125000 0.000000 0.125000 ( 0.125000)
scanf 2.984000 0.032000 3.016000 ( 3.031000)

kind regards -botp


=20
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,160
Latest member
CollinStri
Top