Skip to content

Instantly share code, notes, and snippets.

@jef-sure jef-sure/debitors.pl
Last active May 6, 2019

Embed
What would you like to do?
#!/usr/bin/perl
use v5.12;
use warnings;
use JSON::XS;
use List::Util qw(first);
use Time::HiRes 'time';
use File::Map 'map_file';
binmode STDOUT, ':utf8';
my $t0 = time;
die "Specify input file as first argument" unless defined $ARGV[0] && -f $ARGV[0];
map_file my $jsontext, $ARGV[0], '<';
my $t1 = time;
my $data = decode_json $jsontext;
my $t2 = time;
say "decoded JSON with reading in " . ($t2 - $t1) . " sec";
my @debitors;
my %by_phone;
for my $rec (@$data) {
my $name = (ref $rec->{company}) ? $rec->{company}->{name} : $rec->{company};
my @phones;
push @phones, $rec->{phone} if exists $rec->{phone};
push @phones, (ref $rec->{phones}) ? @{$rec->{phones}} : ($rec->{phones});
my $ph = first {exists $by_phone{$_}} @phones;
if (defined $ph) {
my $di = $by_phone{$ph};
push @{$debitors[$di]->{companies}}, $name
unless scalar grep {$_ eq $name} @{$debitors[$di]->{companies}};
for (@phones) {
$by_phone{$_} = $di;
$debitors[$di]->{phones}->{$_} = undef;
}
$debitors[$di]->{debt} += $rec->{debt};
} else {
push @debitors, {
companies => [$name],
debt => $rec->{debt},
phones => {map {$_ => undef} @phones},
};
$by_phone{$_} = $#debitors for @phones;
}
}
my $t3 = time;
say "aggregated in " . ($t3 - $t2) . " sec";
{
local $" = ", ";
for my $debtor (@debitors) {
say "\nCompany names:\t@{ $debtor->{companies} }";
say "Total debt:\t$debtor->{debt}";
say "Phone numbers:\t@{[sort keys %{ $debtor->{phones} }]}";
}
}
say "\nTotal " . (time - $t0) . " sec";
__END__
decoded JSON with reading in 0.854000091552734 sec
aggregated in 2.73668193817139 sec
Company names: Рога и копыта, Первая коллекторская, Шестерочка
Total debt: 910000000
Phone numbers: 123, 2128506, 234, 456, 788, 789
Company names: Святой престол, Казачий спас
Total debt: 433200000
Phone numbers: 234567, 345678, 666
Total 3.59080910682678 sec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.