1

I have a list of items and a script which generates two lines of csv for each item. May I add two lines at once to csv generator? I want something like this:

CSV.generate do |csv|
  items.each do |item|
    csv << rows(item)
  end
end

def rows(item)
  return \
    ['value1', 'value2', 'value2'],
    ['value3', 'value4', 'value5']
end

But csv << can't receive two lines at once.

Now my the best code is:

CSV.generate do |csv|
  items.each do |item|
    rows(item).each { |row| csv << row } 
  end
end

Update: Now the best code without adding two line at once looks like:

CSV.generate do |csv|
  items.
    flat_map(&method(:rows)).
    each(&csv.method(:<<))
end

2 Answers 2

1
CSV.generate do |csv|
  csv << items.flat_map(&method(:rows))
end
Sign up to request clarification or add additional context in comments.

3 Comments

This doesn't generate clean CSV string, but rather something like that: "[""value1"", ""value2"",... (tested on Ruby 2.2.4)
I like an idea with &method(:rows) but the code gives wrong result.
@IlyaLavrov You can make it work by doing items.flat_map(&method(:rows)).each(&csv.method(:<<)), but your version (from the question) is IMO soo much more cleaner.
1

Array#push or Array#append work the same way, and can take multiple arguments. Edit: As it turns out, CSV.generate yields a CSV object which has neither of those methods.

You can also do it like this:

CSV.generate do |csv|
  items.each do |item|
    r = rows(item)
    csv << r[0] << r[1]
  end
end

2 Comments

CSV object doesn't have append method
@TeWu Thanks, I didn't notice.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.