Confusion with CSV::filter output

Code :

require 'csv'

content = <<CSV
id,first name,last name,age,sex
12,arup,rakshit,26,M
11,ayan,das,25,M
44,puja,roy,19,F
18,Dolly,Sen,21,F
CSV

File.write('a.csv',content)

CSV.foreach('a.csv') do |row|
  p row
end

**output**

# >> ["id", "first name", "last name", "age", "sex"]
# >> ["12", "arup", "rakshit", "26", "M"]
# >> ["11", "ayan", "das", "25", "M"]
# >> ["44", "puja", "roy", "19", "F"]
# >> ["18", "Dolly", "Sen", "21", "F"]

Till now perfect. But why the same is not happening with CSV::filter
(http://www.ruby-doc.org/stdlib-2.1.0/libdoc/csv/rdoc/CSV.html#method-c-filter)
method. I am not getting the rows, rather than name of the file twice.
What wrong I did ?

CSV.filter('a.csv',:col_sep => ",") do |csv|
  p csv
end

# >> ["a.csv"]
# >> a.csv

···

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

I fixed my code :

require 'csv'

content = <<CSV
id,first name,last name,age,sex
12,arup,rakshit,26,M
11,ayan,das,25,M
44,puja,roy,19,F
18,Dolly,Sen,21,F
CSV

File.write('a.csv',content)

#CSV.foreach('a.csv') do |row|
# p row
#end

input = File.new('a.csv','r')
output = File.new('b.csv','w')

CSV.filter(input,output,:col_sep => ",",:headers => true) do |csv|
  csv['status'] = "eligible" if csv['sex'] == "F"
end
output.close

CSV.foreach('b.csv') do |row|
  p row
end

# >> ["12", "arup", "rakshit", "26", "M"]
# >> ["11", "ayan", "das", "25", "M"]
# >> ["44", "puja", "roy", "19", "F", "eligible"]
# >> ["18", "Dolly", "Sen", "21", "F", "eligible"]

Question : why ['id','first name','last name','age','sex'] is missing
from the output and how to add it ?

···

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

Try...

CSV.filter(input,output,:col_sep => ",",:headers => true,
:return_headers => true) do |csv|

Abinoam Jr.

···

On Sat, Feb 15, 2014 at 8:02 AM, Arup Rakshit <lists@ruby-forum.com> wrote:

I fixed my code :

require 'csv'

content = <<CSV
id,first name,last name,age,sex
12,arup,rakshit,26,M
11,ayan,das,25,M
44,puja,roy,19,F
18,Dolly,Sen,21,F
CSV

File.write('a.csv',content)

#CSV.foreach('a.csv') do |row|
# p row
#end

input = File.new('a.csv','r')
output = File.new('b.csv','w')

CSV.filter(input,output,:col_sep => ",",:headers => true) do |csv|
  csv['status'] = "eligible" if csv['sex'] == "F"
end
output.close

CSV.foreach('b.csv') do |row|
  p row
end

# >> ["12", "arup", "rakshit", "26", "M"]
# >> ["11", "ayan", "das", "25", "M"]
# >> ["44", "puja", "roy", "19", "F", "eligible"]
# >> ["18", "Dolly", "Sen", "21", "F", "eligible"]

Question : why ['id','first name','last name','age','sex'] is missing
from the output and how to add it ?

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

Abinoam Jr. wrote in post #1136756:

Try...

CSV.filter(input,output,:col_sep => ",",:headers => true,
:return_headers => true) do |csv|

Tried and worked.. Thanks as always.

require 'csv'

content = <<CSV
id,first name,last name,age,sex
12,arup,rakshit,26,M
11,ayan,das,25,M
44,puja,roy,19,F
18,Dolly,Sen,21,F
CSV

File.write('a.csv',content)

#CSV.foreach('a.csv') do |row|
# p row
#end

input = File.new('a.csv','r')
output = File.new('b.csv','w')

CSV.filter(input,output,:col_sep => ",",:headers => true,:return_headers
=> true) do |csv|
  next csv['status'] = "eligible" if csv['sex'] == "F"
  csv['status'] = ""
end
output.close

CSV.foreach('b.csv') do |row|
  p row
end
# >> ["id", "first name", "last name", "age", "sex", ""]
# >> ["12", "arup", "rakshit", "26", "M", ""]
# >> ["11", "ayan", "das", "25", "M", ""]
# >> ["44", "puja", "roy", "19", "F", "eligible"]
# >> ["18", "Dolly", "Sen", "21", "F", "eligible"]

Now you can see, I have added one more column "status", inside the
block, can this be added to the header row, and get the output as -

["id", "first name", "last name", "age", "sex", "status"] ?

···

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

CSV.filter(input,output,:col_sep => ",",:headers => true,
:return_headers => true) do |csv|
  csv << 'status' if csv.header_row?
  csv['status'] = "eligible" if csv['sex'] == "F"
end

But I bet there's a more elegant (and optimized) way to do it.
I think you should add the row "before" the filter, so you'll do it
once, and not test it each line.

Abinoam Jr.

···

On Sat, Feb 15, 2014 at 10:22 AM, Arup Rakshit <lists@ruby-forum.com> wrote:

Abinoam Jr. wrote in post #1136756:

Try...

CSV.filter(input,output,:col_sep => ",",:headers => true,
:return_headers => true) do |csv|

Tried and worked.. Thanks as always.

require 'csv'

content = <<CSV
id,first name,last name,age,sex
12,arup,rakshit,26,M
11,ayan,das,25,M
44,puja,roy,19,F
18,Dolly,Sen,21,F
CSV

File.write('a.csv',content)

#CSV.foreach('a.csv') do |row|
# p row
#end

input = File.new('a.csv','r')
output = File.new('b.csv','w')

CSV.filter(input,output,:col_sep => ",",:headers => true,:return_headers
=> true) do |csv|
  next csv['status'] = "eligible" if csv['sex'] == "F"
  csv['status'] = ""
end
output.close

CSV.foreach('b.csv') do |row|
  p row
end
# >> ["id", "first name", "last name", "age", "sex", ""]
# >> ["12", "arup", "rakshit", "26", "M", ""]
# >> ["11", "ayan", "das", "25", "M", ""]
# >> ["44", "puja", "roy", "19", "F", "eligible"]
# >> ["18", "Dolly", "Sen", "21", "F", "eligible"]

Now you can see, I have added one more column "status", inside the
block, can this be added to the header row, and get the output as -

["id", "first name", "last name", "age", "sex", "status"] ?

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

Abinoam Jr. wrote in post #1136762:

CSV.filter(input,output,:col_sep => ",",:headers => true,
:return_headers => true) do |csv|
  csv << 'status' if csv.header_row?
  csv['status'] = "eligible" if csv['sex'] == "F"
end

Yes, it is done! Thank you very much!

···

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