1

I have three text files with the exact same type of information but with different delimiters. One is a CSV, one uses spaces as delimiters, and the last one uses | (pipe) as the delimiter. The delimiters are different, but each row in all of the files has exactly the same format. So in the pipe-delimited file, the format is FirstName | LastName | DOB | City | State | ZIP (there is a space before and after each pipe). The other two files use the exact same order but with the other delimiters. All rows are unique. The files do not have headers.

I want to go through all of these files and create an instance of my Person object for each row. The class looks like this:

class Person
  attr_reader :first_name, :last_name, :d_o_b, :city, :state, :zip

  def initialize(first_name, last_name, ...)
    @first_name = first_name
    @last_name = last_name
    ...
  end

  ...

  etc.

end

I want to parse this data and create the objects in the cleanest and most readable way -- performance/scaling/etc. are unimportant here. What approach would be best for doing this? My initial idea is to convert all of the files to CSV somehow (perhaps with a gsub), then make a nested array from this data, and then iterate over the array to create the objects, but I am looking for any possible better/cleaner ideas.

2 Answers 2

2

Something along these lines should work. You'll have to be careful if your city names have commas or spaces.

files = ['file1.txt', 'file2.txt']

people = []
files.each do |f|
  File.open(f).each do |line|

    # Split line along any of the delimeters
    args = line.strip.split(/[ ,\|]+/)

    # The * (splat) unpacks the array into an argument list
    people << Person.new(*args)
  end
end
Sign up to request clarification or add additional context in comments.

Comments

1

FasterCSV allows you to specify column delimiter

FasterCSV.read(path, { :headers => false, :col_sep => "|", :skip_blanks => true })

FasterCSV.read(path, {col_sep: " ", skip_blanks: false})

Comments

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.