0

I can’t seem to get this to work

I know I can do this with csv gem but Im trying out new stuff and I want to do it this way. All Im trying to do is to read lines in from a csv and then create one array from each line. I then want to put the second element in each array.

So far I have

filed="/Users/me/Documents/Workbook3.csv"

if File.exists?(filed)
  File.readlines(filed).map {|d| puts d.split(",").to_a}
else puts "No file here”

The problem is that this creates one array which has all the lines in it whereas I want a separate array for each line (perhaps an array of arrays?) Test data

Trade date,Settle date,Reference,Description,Unit cost (p),Quantity,Value (pounds)
04/09/2014,09/09/2014,S5411,Plus500 Ltd ILS0.01 152 @  419,419,152,624.93
02/09/2014,05/09/2014,B5406,Biomarin Pharmaceutical Com Stk USD0.001 150 @  4284.75,4284.75,150,-6439.08
29/08/2014,03/09/2014,S5398,Hargreaves Lansdown plc Ordinary 0.4p 520 @  1116.84,1116.84,520,5795.62

What I would like

S5411
B5406
S5398
3
  • try puts d.split(',')[2] Commented Sep 11, 2015 at 6:54
  • I still get the problem that its treated as one line so I just get one array. Perhaps readlines ignores newlines or something? Commented Sep 11, 2015 at 7:02
  • readlines is of course aware of newlines, that's the whole point ;-) Please show your output. Commented Sep 11, 2015 at 7:04

2 Answers 2

2

Let write your data to a file:

s =<<THE_BITTER_END
Trade date,Settle date,Reference,Description,Unit cost (p),Quantity,Value (pounds)
04/09/2014,09/09/2014,S5411,Plus500 Ltd ILS0.01 152 @  419,419,152,624.93
02/09/2014,05/09/2014,B5406,Biomarin Pharmaceutical Com Stk USD0.001 150 @  4284.75,4284.75,150,-6439.08
29/08/2014,03/09/2014,S5398,Hargreaves Lansdown plc Ordinary 0.4p 520 @  1116.84,1116.84,520,5795.62
THE_BITTER_END

IO.write('temp',s)
  #=> 363

We can then do this:

arr = File.readlines('temp').map { |s| s.split(',') }
  #=> [["Trade date", "Settle date", "Reference", "Description", "Unit cost (p)",
        "Quantity", "Value (pounds)\n"],
       ["04/09/2014", "09/09/2014", "S5411",
        "Plus500 Ltd ILS0.01 152 @  419", "419", "152", "624.93\n"],
       ["02/09/2014", "05/09/2014", "B5406",
        "Biomarin Pharmaceutical Com Stk USD0.001 150 @  4284.75",
        "4284.75", "150", "-6439.08\n"],
       ["29/08/2014", "03/09/2014", "S5398",
        "Hargreaves Lansdown plc Ordinary 0.4p 520 @  1116.84", "1116.84",
        "520", "5795.62\n"]] 

The values you want begin in the second element of arr and is the third element in each of those arrays. Therefore, you can pluck them out as follows:

arr[1..-1].map { |a| a[2] }
  #=> ["S5411", "B5406", "S5398"] 

Adopting @Stefan's suggestion of putting [2] within the block containing split, we can write this more compactly as follows:

File.readlines('temp')[1..-1].map { |s| s.split(',')[2] }
  #=> ["S5411", "B5406", "S5398"] 
Sign up to request clarification or add additional context in comments.

4 Comments

I'm not sure that I understand why you have to write it to a temporary file before reading it in
@SebastianZeki an example should be "self contained", i.e. it should include all the code and data that's needed to run it. See sscce.org
@Cary Why you have to write it to a temporary file before reading it in. Is it something to do with csv newlines?
Sebastian, I didn't have to. I could have assumed you read the file containing the string I called s in the heredoc.I did it for the reason @Stefan gave. It was only one extra line. It had nothing to do with CSV.
2

You can also use built-in class CSV to do this very easily.

require "csv"

s =<<THE_BITTER_END
Trade date,Settle date,Reference,Description,Unit cost (p),Quantity,Value (pounds)
04/09/2014,09/09/2014,S5411,Plus500 Ltd ILS0.01 152 @  419,419,152,624.93
02/09/2014,05/09/2014,B5406,Biomarin Pharmaceutical Com Stk USD0.001 150 @  4284.75,4284.75,150,-6439.08
29/08/2014,03/09/2014,S5398,Hargreaves Lansdown plc Ordinary 0.4p 520 @  1116.84,1116.84,520,5795.62
THE_BITTER_END

arr = CSV.parse(s, :headers=>true).collect { |row| row["Reference"] }
p arr
#=> ["S5411", "B5406", "S5398"]

PS: I have borrowed the string from @Cary's answer

1 Comment

This is a much cleaner solution especially given the fact that the OP stated a CSV file. This is a great example of an XY Problem and answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.