52

If I have an array of strings e.g.

a = ['a', 'b', 'c', 'd']

and I want to output the elements, to a file (e.g. .txt) one per line. So far I have:

File.new("test.txt", "w+")
File.open("test.txt", "w+") do |i|
    i.write(a)
end

This gives me the array on one line of the test.txt file. How can I iterate over the array, adding each value to a new line of the file?

edc505
  • 871
  • 3
  • 8
  • 14

5 Answers5

122

Either use Array#each to iterate over your array and call IO#puts to write each element to the file (puts adds a record separator, typically a newline character):

File.open("test.txt", "w+") do |f|
  a.each { |element| f.puts(element) }
end

Or pass the whole array to puts:

File.open("test.txt", "w+") do |f|
  f.puts(a)
end

From the documentation:

If called with an array argument, writes each element on a new line.

Stefan
  • 109,145
  • 14
  • 143
  • 218
23

There is a quite simpler solution :

IO.write("file_name.txt", your_array.join("\n"))
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
  • @Dika Suparlan, welcome to SO. A little explanation is also helpful. Not only does it validate your answer but it gives the OP an indication of what they need to do both with the current issue and potentially in future situations. Im sure I'm not alone in wanting to learn from the SO community rather than just being given solutions. The greatest sense of success is in overcoming a good challenge. ;-) – Phill Healey Sep 20 '16 at 13:47
  • This should be the preferred answer. From the doc -- http://ruby-doc.org/core-2.4.2/IO.html -- IO.write(name, string [, offset] [, opt]) → integer --- Opens the file, optionally seeks to the given offset, writes string, then returns the length written. write ensures the file is closed before returning. If offset is not given, the file is truncated. Otherwise, it is not truncated. – Purplejacket Dec 01 '17 at 18:33
9

As an alternate, you could simply join the array with "\n" so that each element is on a new line, like this:

a = %w(a b c d)

File.open('test.txt', 'w') {|f| f.write a.join("\n")}

If you don't want to override the values already in the text file so that you're simply adding new information to the bottom, you can do this:

a = %w(a b c d)

File.open('test.txt', 'a') {|f| f << "\n#{a.join("\n")}"}
tigeravatar
  • 26,199
  • 5
  • 30
  • 38
4

Use Array#each to iterate each element. When writing to the file, make sure you append newline(\n), or you will get a file with abcd as content:

a = ['a', 'b', 'c', 'd']
File.open('test.txt', 'w') do |f|
  a.each do |ch|
    f.write("#{ch}\n")
  end
end
falsetru
  • 357,413
  • 63
  • 732
  • 636
3

Another simple solution:

directory = "#{Rails.root}/public/your_directory" #create your_directory before
file_name = "your_file.txt"
path = File.join(directory, file_name)
File.open(path, "wb") { |f| f.write(your_array.join("\n")) }
andriy
  • 111
  • 3