Array.map! + delete_if possible?

I have an array of strings that I need to modify. I either need to
replace the string or delete the entry altogether. The only way I have
been able to do this is :

arr.delete("")

(0..arr.size).each do |i|
  if arr[i].to_i == 1201
    arr[i]=arr[i].to_s[8..-1].gsub(/"[^"]*"/,'::').gsub(/".*/,"::")
  else
    arr[i-1] = arr[i-1] + arr[i].to_s[4..-1].to_s.gsub(/\s*/,"")
    arr[i]=nil
  end
end

arr.delete(nil)

Is there a better way ?

Also inside the else I get char 4->-1 of a string, but then need to
explicitly change it into a string for gsub to work. Otherwise it gives
me an undefined method 'gsub' for nilNilClass error.

···

--
Posted via http://www.ruby-forum.com/.

Kassym Dorsel wrote in post #1022385:

(0..arr.size).each do |i|

arr = [1, 2, 3]
(0..arr.size).each do |index|
  p arr[index]
end

--output:--
1
2
3
nil

  if arr[i].to_i == 1201
    arr[i]=arr[i].to_s[8..-1].gsub(/"[^"]*"/,'::').gsub(/".*/,"::")
  else
    arr[i-1] = arr[i-1] + arr[i].to_s[4..-1].to_s.gsub(/\s*/,"")
    arr[i]=nil
  end
end

What if the first string in the array doesn't equal 1201?

···

--
Posted via http://www.ruby-forum.com/\.

I honestly have no idea what this is supposed to do.

···

On Fri, Sep 16, 2011 at 5:03 PM, Kassym Dorsel <k.dorsel@gmail.com> wrote:

I have an array of strings that I need to modify. I either need to
replace the string or delete the entry altogether. The only way I have
been able to do this is :

arr.delete("")

(0..arr.size).each do |i|
if arr[i].to_i == 1201
   arr[i]=arr[i].to_s[8..-1].gsub(/"[^"]*"/,'::').gsub(/".*/,"::")
else
   arr[i-1] = arr[i-1] + arr[i].to_s[4..-1].to_s.gsub(/\s*/,"")
   arr[i]=nil
end
end

arr.delete(nil)

Is there a better way ?

Also inside the else I get char 4->-1 of a string, but then need to
explicitly change it into a string for gsub to work. Otherwise it gives
me an undefined method 'gsub' for nilNilClass error.

--
Posted via http://www.ruby-forum.com/\.

Is there a better way ?

Probably :slight_smile:

But, I also have a hard time trying to understand what you want to do.
Can you post some sample array(s) and some sample output that you want to see?

Harry

I have an array of strings that I need to modify. I either need to
replace the string or delete the entry altogether.

irb(main):010:0> a = 10.times.to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):011:0> a.map! {|i| i.odd? ? i : nil}.compact!
=> [1, 3, 5, 7, 9]
irb(main):012:0> a
=> [1, 3, 5, 7, 9]

The only way I have
been able to do this is :

arr.delete("")

(0..arr.size).each do |i|

arr.each_index do |i|

   if arr[i].to_i == 1201
     arr[i]=arr[i].to_s[8..-1].gsub(/"[^"]*"/,'::').gsub(/".*/,"::")

Maybe:

arr[i] = arr[i].to_s[8..-1].gsub(/"[^"]*(?:"|\z)/,'::')

Is this really what you want? First you convert all quoted sequences to "::" and then you remove everything after the single remaining quote to the end by "::"?

   else
     arr[i-1] = arr[i-1] + arr[i].to_s[4..-1].to_s.gsub(/\s*/,"")

arr[i-1] << arr[i].to_s[4..-1].to_s.gsub(/\s*/,"")

     arr[i]=nil
   end
end

arr.delete(nil)

arr.compact!

Is there a better way ?

First we should clarify what you are doing. As far as I can see you want to iterate the array and either modify element i or convert element i and append it to element i - 1. From this it is clear that you cannot use #map or #map! because those methods are intended to modify the current object.

Also inside the else I get char 4->-1 of a string, but then need to
explicitly change it into a string for gsub to work. Otherwise it gives
me an undefined method 'gsub' for nilNilClass error.

So your statement that you have a String is not correct. You are probably experiencing this effect

irb(main):017:0> s="123"
=> "123"
irb(main):018:0> s[4..-1]
=> nil

A bit of sample data would be helpful...

Kind regards

  robert

···

On 17.09.2011 00:03, Kassym Dorsel wrote:

Thanks for the answer. Here is the initial array.

arr[0]=1201 0 "userid" 1202 0 "lname" 1203 0 "mname" 1204 0 "lname" 1217
0 "password"
arr[1]=
arr[2]=4 0 emailaddress
arr[3]=1201 0 "userid" 1202 0 "lname" 1203 0 "mname" 1204 0 "lname" 1217
0 "password"
arr[4]=
arr[5]=1201 0 "userid" 1202 0 "lname" 1203 0 "mname" 1204 0 "lname" 1217
0 "password"

The email address line is random depending if the user inputed one or
not and may or may not show up.

I want to end up with this :

arr[0]=userid::lname::mname::lname::password::emailaddress
etc

In the end I iterate over this array and input the info data into a
database. I don't think I can combine both loops because I need to check
index for the email and if found go back to index-1 for the rest of the
info and then input into database.

Also instead of using arr.delete("") could I not use
arr.delete(/[^14}*/), but does not seem to work.

@7stud : Good catch about the first entry not having 1201, I missed
that, but there is no chance of that happening.

···

--
Posted via http://www.ruby-forum.com/.

irb(main):010:0> a = 10.times.to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):011:0> a.map! {|i| i.odd? ? i : nil}.compact!
=> [1, 3, 5, 7, 9]
irb(main):012:0> a
=> [1, 3, 5, 7, 9]

A bit simpler:

a = (1..10).to_a # don't really need the to_a for this, but hey

=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

a.select! { |e| e.odd? }

=> [1, 3, 5, 7, 9]

a

=> [1, 3, 5, 7, 9]

···

On Sun, Sep 18, 2011 at 12:30 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

Thanks for the answer. Here is the initial array.

arr[0]=1201 0 "userid" 1202 0 "lname" 1203 0 "mname" 1204 0 "lname" 1217
0 "password"
arr[1]=
arr[2]=4 0 emailaddress
arr[3]=1201 0 "userid" 1202 0 "lname" 1203 0 "mname" 1204 0 "lname" 1217
0 "password"
arr[4]=
arr[5]=1201 0 "userid" 1202 0 "lname" 1203 0 "mname" 1204 0 "lname" 1217
0 "password"

The email address line is random depending if the user inputed one or
not and may or may not show up.

I want to end up with this :

arr[0]=userid::lname::mname::lname::password::emailaddress
etc

In the end I iterate over this array and input the info data into a
database. I don't think I can combine both loops because I need to check
index for the email and if found go back to index-1 for the rest of the
info and then input into database.

I picked the approach to identify fields by their number and create
records based on that.

Also instead of using arr.delete("") could I not use
arr.delete(/[^14}*/), but does not seem to work.

Kind regards

robert

···

On Mon, Sep 19, 2011 at 5:24 PM, Kassym Dorsel <k.dorsel@gmail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

My bad. I left the conversion out of my example. With conversion you
cannot use #select. This is a better example:

irb(main):004:0> a = 10.times.to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):005:0> a.map! {|i| i.odd? ? ('*' * i) : nil}.compact!
=> ["*", "***", "*****", "*******", "*********"]

But anyway, this scenario is also not what the OP apparently wants.

Kind regards

robert

···

On Sun, Sep 18, 2011 at 2:05 PM, Adam Prescott <adam@aprescott.com> wrote:

On Sun, Sep 18, 2011 at 12:30 PM, Robert Klemme > <shortcutter@googlemail.com> wrote:

irb(main):010:0> a = 10.times.to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):011:0> a.map! {|i| i.odd? ? i : nil}.compact!
=> [1, 3, 5, 7, 9]
irb(main):012:0> a
=> [1, 3, 5, 7, 9]

A bit simpler:

a = (1..10).to_a # don't really need the to_a for this, but hey

=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

a.select! { |e| e.odd? }

=> [1, 3, 5, 7, 9]

a

=> [1, 3, 5, 7, 9]

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/