App-CSVUtils
view release on metacpan or search on metacpan
lib/App/CSVUtils/csv_lookup_fields.pm view on Meta::CPAN
$r->{target_fields_idx} = [];
$r->{target_fields} = [];
$r->{target_data_rows} = [];
},
on_input_header_row => sub {
my $r = shift;
if ($r->{input_filenum} == 1) {
$r->{target_fields} = $r->{input_fields};
$r->{target_fields_idx} = $r->{input_fields_idx};
$r->{output_fields} = $r->{input_fields};
} else {
$r->{source_fields} = $r->{input_fields};
$r->{source_fields_idx} = $r->{input_fields_idx};
}
},
on_input_data_row => sub {
my $r = shift;
if ($r->{input_filenum} == 1) {
push @{ $r->{target_data_rows} }, $r->{input_row};
} else {
push @{ $r->{source_data_rows} }, $r->{input_row};
}
},
after_close_input_files => sub {
my $r = shift;
my $ci = $r->{util_args}{ignore_case};
# build lookup table
my %lookup_table; # key = joined lookup fields, val = source row idx
for my $row_idx (0..$#{$r->{source_data_rows}}) {
my $row = $r->{source_data_rows}[$row_idx];
my $key = join "|", map {
my $field = $r->{lookup_fields}[$_][1];
my $field_idx = $r->{source_fields_idx}{$field};
my $val = defined $field_idx ? $row->[$field_idx] : "";
$val = lc $val if $ci;
$val;
} 0..$#{ $r->{lookup_fields} };
$lookup_table{$key} //= $row_idx;
}
#use DD; dd { lookup_fields=>$r->{lookup_fields}, fill_fields=>$r->{fill_fields}, lookup_table=>\%lookup_table };
# fill target csv
my $num_filled = 0;
for my $row (@{ $r->{target_data_rows} }) {
my $key = join "|", map {
my $field = $r->{lookup_fields}[$_][0];
my $field_idx = $r->{target_fields_idx}{$field};
my $val = defined $field_idx ? $row->[$field_idx] : "";
$val = lc $val if $ci;
$val;
} 0..$#{ $r->{lookup_fields} };
#say "D:looking up '$key' ...";
if (defined(my $row_idx = $lookup_table{$key})) {
#say " D:found";
my $row_filled;
my $source_row = $r->{source_data_rows}[$row_idx];
for my $field (keys %{$r->{fill_fields}}) {
my $target_field_idx = $r->{target_fields_idx}{$field};
next unless defined $target_field_idx;
my $source_field_idx = $r->{source_fields_idx}{ $r->{fill_fields}{$field} };
next unless defined $source_field_idx;
$row->[$target_field_idx] =
$source_row->[$source_field_idx];
$row_filled++;
}
$num_filled++ if $row_filled;
}
unless ($r->{util_args}{count}) {
$r->{code_print_row}->($row);
}
} # for target data row
if ($r->{util_args}{count}) {
$r->{result} = [200, "OK", $num_filled];
}
},
);
1;
# ABSTRACT: Fill fields of a CSV file from another
__END__
=pod
=encoding UTF-8
=head1 NAME
App::CSVUtils::csv_lookup_fields - Fill fields of a CSV file from another
=head1 VERSION
This document describes version 1.036 of App::CSVUtils::csv_lookup_fields (from Perl distribution App-CSVUtils), released on 2025-02-04.
=head1 FUNCTIONS
=head2 csv_lookup_fields
Usage:
csv_lookup_fields(%args) -> [$status_code, $reason, $payload, \%result_meta]
Fill fields of a CSV file from another.
Example input:
# report.csv
client_id,followup_staff,followup_note,client_email,client_phone
101,Jerry,not renewing,
299,Jerry,still thinking over,
734,Elaine,renewing,
( run in 0.905 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )