amy jones amy jones - 3 months ago 8
Ruby Question

Using ruby to write out to a csv file from sqlite database

I could not figure out the functionality of the below Ruby program. I know we are opening xxx.csv & creating 9 columns, but I don't understand the following:

out <<
,
do |out|
,
(1..10).map{|i| "r" + i.to_s}
(1..10 rep a set of 1 to 10 ???),
map
method and its argument, and
flatten.join("\t") + "\n"
.

File.open("xxxx.csv", "w") do |out|
out << [
'x', 'y', 'l', 'b',
'r', 'v', (1..10).map{|i| "r" + i.to_s},
'xxx', 'd'
].flatten.join("\t") + "\n"


Example of the data:
13/#137/2011/0/15/5.8/5/4.....2..4/PG


I'm learning Ruby and programming in general and apologize if my question is a basic one.

Thanks
Amy

Answer

See also Export content of a SQLite3 table in CSV to get an answer on your problem.


But to explain the code. Lets try it in parts:

p (1..10).map{|i| "r" + i.to_s}

result:

["r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"]

Now lets do it in details: (1..10) is a Range object. If you execute

(1..10).to_a

you get get an array from 1 to 10: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].

map loops on the objects of the range and and creates a new array with the result of the given block. So (1..10).map{|i| "r" + i.to_s} loops on all values of the range 1 to 10, gives the value to the block internal variable i and builds a new String with r and (+) the string representation of the number i (to_s means to string).

In total you get an array like this:

["x", "y", "l", "b", "r", "v", 
   ["r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"], 
  "xxx", "d"
]

flatten makes array flat. If there is an array in an array, then flatten resolve the inner array(s) and makes it 'flat'

Example:

[1,[2,3]].flatten  #[1, 2, 3]

join takes all entries of the array and concatenates them into a string. The (optional) parameter defines the content between two elements. So in your code you get all entries as a csv-line with tab-separartor.

And in the end a newline is added.

In steps:

["x", "y", "l", "b", "r", "v", 
   ["r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"], 
  "xxx", "d"
].flatten

results in

["x", "y", "l", "b", "r", "v", 
   "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", #No inner array any longer
  "xxx", "d"
]

Then the join is done:

["x", "y", "l", "b", "r", "v", 
   "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 
  "xxx", "d"
].join("\t")

result:

"x\ty\tl\tb\tr\tv\tr1\tr2\tr3\tr4\tr5\tr6\tr7\tr8\tr9\tr10\txxx\td"
Comments