[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

FasterCSV joining rows?

Kris Windham

11/8/2008 7:34:00 PM

I was wondering if anyone could point me in the right direction for
solving the following problem:

I am appending to a csv every time a database change is made in a Rails
app I am working on.
I would like to join the rows together based on the first field.
If this field has duplicates, I would like to combine all values in each
row into one row.
Each row will have only one updated field.
All other fields will be denoted with an asterisk.
The following is an example:

100000000,myemail@ischanged.com,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
100000000,*,*,888-888-8888,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
100000000,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,My Company was
changed,*,*,*,*,*
100000000,*,*,*,*,*,*,*,*,*,*,*,303 changed work
address,*,*,*,*,*,*,*,*,*,*

I need the above to look like the following:

100000000,myemail@ischanged.com,*,888-888-8888,*,*,*,*,*,*,*,*,*,303
changed work address,*,*,*,*,My Company was changed,*,*,*,*,*

Any help would be appreciated.

Thanks,

Kris Windham
--
Posted via http://www.ruby-....

1 Answer

James Gray

11/8/2008 9:42:00 PM

0

On Nov 8, 2008, at 1:34 PM, Kris Windham wrote:

> I was wondering if anyone could point me in the right direction for
> solving the following problem:

I'll try.

> I am appending to a csv every time a database change is made in a
> Rails
> app I am working on.
> I would like to join the rows together based on the first field.
> If this field has duplicates, I would like to combine all values in
> each
> row into one row.
> Each row will have only one updated field.
> All other fields will be denoted with an asterisk.
> The following is an example:
>
> 100000000
> ,myemail@ischanged.com,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
> 100000000,*,*,888-888-8888,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
> 100000000,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,My Company was
> changed,*,*,*,*,*
> 100000000,*,*,*,*,*,*,*,*,*,*,*,303 changed work
> address,*,*,*,*,*,*,*,*,*,*
>
> I need the above to look like the following:
>
> 100000000,myemail@ischanged.com,*,888-888-8888,*,*,*,*,*,*,*,*,*,303
> changed work address,*,*,*,*,My Company was changed,*,*,*,*,*
>
> Any help would be appreciated.

Does code like the following give you any ideas?

#!/usr/bin/env ruby -wKU

require "rubygems"
require "faster_csv"

data = <<END_DATA
100000000
,myemail@ischanged.com,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
100000000,*,*,888-888-8888,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
100000000,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,My Company was
changed,*,*,*,*,*
100000000,*,*,*,*,*,*,*,*,*,*,*,303 changed work
address,*,*,*,*,*,*,*,*,*,*
END_DATA

# rebuild records from changelog
records = Hash.new
FCSV.parse(data, :converters => lambda { |f| f == "*" ? nil : f }) do |
row|
key = row.shift
old = Array(records[key])
fields = [old, row].map { |r| r.size }.max
records[key] = (0...fields).map { |i| row[i] || old[i] }
end

# write records
FCSV do |csv|
records.each do |key, record|
csv << [key, *record].map { |f| f || "*" }
end
end
# >> 100000000,myemail@ischanged.com,*,888-888-8888,*,*,*,*,*,*,*,*,
303 changed work address,*,*,*,*,My Company was changed,*,*,*,*,*

__END__

Hope that helps.

James Edward Gray II