Skip to content

Instantly share code, notes, and snippets.

@larsen
Created September 21, 2011 20:01
Show Gist options
  • Save larsen/1233130 to your computer and use it in GitHub Desktop.
Save larsen/1233130 to your computer and use it in GitHub Desktop.
wishful thinking #csv
Example 1
use CSV::Stream;
use CSV::Stream::Column;
my $planets_stream = CSV::Stream->new(
columns => [
CSV::Stream::Column->new( name => 'Name' ),
CSV::Stream::Column->new( name => 'Distance' ),
CSV::Stream::Column->new(
name => 'Temperature'
transformation => sub {
my $self = shift;
print $self->value * 10;
}
),
]
filename => $filename,
separator => q{;},
# ... usual Text::CSV_XS configuration ...
);
my $planets_stream_out = CSV::Stream->new(
filename => $output_filename
);
# Loops over every columns, applying transformations if any
# Columns names and ordering are the same
#
CSV::Stream->stream( $planets_stream => $planets_stream_out );
-----------------------------------------------------------------------
Example 2 (combining columns into new one, keeping the others)
use CSV::Stream;
use CSV::Stream::Column;
my $planets_stream = CSV::Stream->new(
columns => [
CSV::Stream::Column->new( name => 'Name' ),
CSV::Stream::Column->new( name => 'Distance' ),
CSV::Stream::Column->new( name => 'Temperature' ),
]
filename => $filename,
separator => q{;},
# ...
);
my $planets_stream_out = CSV::Stream->new(
filename => $output_filename
columns_add => [
# 1. Come fare per specificare che voglio le stesse colonne?
# Ad esempio usando columns_add anziche` colums.
# Il che semplificherebbe anche la semantica di value
# 2. Ha senso passare l'intera riga di partenza?
CSV::Stream::Column->new(
name => 'Orbit'
value => sub {
my $self = shift;
my $original_row = shift;
return $original_row->distance * 3.14;
}
)
]
);
# Loops over every columns, applying transformations if any
CSV::Stream->stream( $planets_stream => $planets_stream_out );
-----------------------------------------------------------------------
Example 3 (combining columns into new one, throwing away the others)
use CSV::Stream;
use CSV::Stream::Column;
my $planets_stream = CSV::Stream->new(
columns => [
CSV::Stream::Column->new( name => 'Name' ),
CSV::Stream::Column->new( name => 'Distance' ),
CSV::Stream::Column->new( name => 'Temperature' ),
]
filename => $filename,
separator => q{;},
# ...
);
my $planets_stream_out = CSV::Stream->new(
filename => $output_filename
columns => [ ], # No original columns
columns_add => [
# 1. Come fare per specificare che voglio le stesse colonne?
# Ad esempio usando columns_add anziche` colums.
# Il che semplificherebbe anche la semantica di value
# 2. Ha senso passare l'intera riga di partenza?
CSV::Stream::Column->new(
name => 'Temperature'
transformation => sub {
my $self = shift;
print $self->value * 10;
}
),
CSV::Stream::Column->new(
name => 'Orbit'
value => sub {
my $self = shift;
my $original_row = shift;
return $original_row->distance * 3.14;
}
)
]
);
# Loops over every columns, applying transformations if any
CSV::Stream->stream( $planets_stream => $planets_stream_out );
-----------------------------------------------------------------------
Example 4 (filter the original)
TODO
-----------------------------------------------------------------------
Example 5 (filter and aggregation, # of lines in output differs from
the original)
use CSV::Stream;
use CSV::Stream::Column;
my $planets_stream = CSV::Stream->new(
columns => [
CSV::Stream::Column->new( name => 'Name' ),
CSV::Stream::Column->new( name => 'Distance' ),
CSV::Stream::Column->new( name => 'Temperature' ),
]
filename => $filename,
separator => q{;},
# ...
);
my $planets_stream_out = CSV::Stream->new(
filename => $output_filename
columns => [
# Ho bisogno di un modo per mantenere un valore
# globale alla computazione. In questo caso sono
# Praticamente due accumulatori (anzi, un accumulatore
# e una serie di etichette)
# Direi che questa colonna potrebbe essere
# un iteratore
CSV::Stream::Column->new(
name => 'Proximity',
value => Class::Stream::Value::Iterator->new(
values => [ qw/
Near
Medium
Far
Outer
/ ]
)
),
CSV::Stream::Column->new(
name => 'Count',
value_accumulator => sub {
my $self = shift;
my $context = shift; # questo dovrebbe essere un oggetto
# che rappresenta la riga che sta
# leggendo
my $distance = $context->current_line->distance;
given( $distance ) {
when ( $_ < 100 ) { $_stash->{ Near }++ }
when ( $_ >= 100 and $_ < 300 ) { $_stash->{ Medium }++ }
when ( $_ >= 300 and $_ < 900 ) { $_stash->{ Far }++ }
when ( $_ >= 900 ) { $_stash->{ Outer }++ }
}
}
value => sub {
my $self = shift;
my $context = shift; # questo invece la riga che
# sta costruendo
my $proximity_label_value =
$context->proximity->value;
return $_stash->{ ucfirst $proximity_label_value };
}
),
]
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment