How to Print to Different Files on the Fly?
How can I print the contents of a dynamically generated and sorted array to different files based on their content?
For example, let's say we have the following multi-dimensional array which is sorted by the second column
[ ['St开发者_Python百科eph', 'Allen', 29], ['Jon', 'Doe', 30], ['Jane', 'Doe', 30], ['Tom', 'Moore', 28] ]
The goal is to have 3 files:
last_name-Allen.txt <-- Contains Steph Allen 29
last_name-Doe.txt <-- Contains Jon Doe 30 Jane Doe 30
last_name-Moore.txt <-- Contains Tom Moore 28
ar = [ ['Steph', 'Allen', 29], ['Jon', 'Doe', 30], ['Jane', 'Doe', 30], ['Tom', 'Moore', 28] ]
grouped = ar.group_by{|el| el[1] }
# {"Allen"=>[["Steph", "Allen", 29]], "Doe"=>[["Jon", "Doe", 30], ["Jane", "Doe", 30]], "Moore"=>[["Tom", "Moore", 28]]}
grouped.each do |last_name, record|
File.open("last_name-#{last_name}.txt",'w') do |f|
f.puts record.join(' ')
end
end
If you wanted to do this in Groovy, you could use the groupBy
method to get a map based on surname like so:
// Start with your list
def list = [ ['Steph', 'Allen', 29], ['Jon', 'Doe', 30], ['Jane', 'Doe', 30], ['Tom', 'Moore', 28] ]
// Group it by the second element...
def grouped = list.groupBy { it[ 1 ] }
println grouped
prints
[Allen:[[Steph, Allen, 29]], Doe:[[Jon, Doe, 30], [Jane, Doe, 30]], Moore:[[Tom, Moore, 28]]]
Then, iterate through this map, opening a new file for each surname and writing the content in (tab separated in this example)
grouped.each { surname, contents ->
new File( "last_name-${surname}.txt" ).withWriter { out ->
contents.each { person ->
out.writeLine( person.join( '\t' ) )
}
}
}
In ruby:
array.each{|first, last, age| open("last_name-#{last}.txt", "a"){|io| io.write([first, last, age, nil].join(" ")}}
It adds an extra space at the end of the file. This is to keep the space when there is another entity to be added.
use a hash with last name as the keys, then iterate over the hash and write each key/value pair to its own file.
In Groovy you can do this:
def a = [['Steph', 'Allen', 29], ['Jon', 'Doe', 30], ['Jane', 'Doe', 30], ['Tom', 'Moore', 28]]
a.each {
def name = "last_name-${it[1]}.txt"
new File(name) << it.toString()
}
Probably there is shorter (groovier) way to do this.
You can create a hash of with "second column" as key and value as "file handle". If you get the key in hash, just fetch file handle and write, else create new file handle and insert in hash.
This answer is in Ruby:
# hash which opens appropriate file on first access
files = Hash.new { |surname| File.open("last_name-#{surname}.txt", "w") }
list.each do |first, last, age|
files[last].puts [first, last, age].join(" ")
end
# closes all the file handles
files.values.each(&:close)
精彩评论