Hi!
Post by Ben MorrowIn Haskell the solution looks like this: [...]
Hmmm. Not likely :)
It looks like Perl is beaten by better libraries
instead of higher elegance and orthogonality.
The latter isn't a problem: Perl mongers have no problem with
that other people think perl is ugly and dirty.
(Maybe simply because it is true.)
But this was an attack to theirs proudness about the all-embracing CPAN.
(So at least i start missing
Set::Bag::Value -or- Set::Scalar::MultiValue.)
This posting is cross-posted to c.l.f only, because even some of the
stuff in the appended code looks familiar at first, it holds
things in it which can cause heart attacks to this guys.
So be warned.
One the other side, it is time that functional programmer came in
contact with the real world, instead always be protected by gloves
called monads, isn't it?
xp&fup.
just kidding,
josef
***@c.l.f: Looking at the appended source on your own risk!
O /
---X----------------------------------------------------------
O \ dedicated_to_a_spammer.pl
#! /usr/bin/env perl
use strict; use warnings;
use Data::Dump 'dump';
my @inp=([0,'a','b'],[1,'c','d'],[2,'e','f'],[3,'g','h'],
[1,'i','j'],[2,'k','l'],[4,'m','n'],[2,'o','p'],
[4,'q','r'],[5,'s','t']);
#helper functions:
#sub distributefirst_as (&@) { ((my $f),$a)=splice @_,0,2; map {
$f->($a,$b=$_) } @_ }
#sub wo_dup { my %e; grep { ! $e{$_}++ } @_ }
# -----------------------------------------------------
print "\ntie variant (first occurence order):\n";
use Tie::Hash::MultiValue;
use Array::Unique;
sub distributefirst { my $t=shift; map { $t => $_ } @_ }
tie my @keys, 'Array::Unique';
tie my %h, 'Tie::Hash::MultiValue';
%h=map { distributefirst @$_ } @inp;
@keys=map { $_->[0] } @inp; # or: List::MoreUtils::each_arrayref(@inp)->()
dump @h{@keys};
# -----------------------------------------------------
print "\nreduce variant (first occurence order):\n";
use List::Util qw'reduce first';
dump @{+reduce { my @t=@$b; push @{$a->{+shift @t}}, @t; $a } {},@inp}
{@{+reduce { (first {$_ eq $b->[0]} @$a) ? $a : [@$a,$b->[0]] }
[],@inp}};
# -----------------------------------------------------
print "\narray based reduce variant (key must be a number):\n";
use List::Util 'reduce';
dump reduce { push @{$a->[$b->[0]]}, @{$b}[1..$#$b]; $a } [],@inp;
#or: dump reduce { push @{$a->[shift $b]}, @$b; $a } [],clone @inp;
# ------------------------------------------------------
print "\nperlish array variant (key must be a number):\n";
my @v;
push @{$v[$_->[0]]}, @{$_}[1..$#$_] for @inp;
dump @v;
# ------------------------------------------------------
print "\npresort variant (alphabetically orderd):\n";
sub butfirst { @_[1..$#_] }; sub deref { @{$_[0]} };
sub clone { map {[@$_]} @_ }
my @sorted=sort { $a->[0] cmp $b->[0] } clone @inp;
dump map { [ butfirst @$_ ] } deref # @{$_}[1..$#$_]
reduce { $a->[$#$a]->[0] ne $b->[0] ? [@$a,$b] :
(push @{$a->[$#$a]},butfirst @$b)&&$a }
[$sorted[0]],butfirst @sorted;
# ------------------------------------------------------
print "\npresort variant2 (alphabetically orderd):\n";
@sorted=sort { $a->[0] cmp $b->[0] } @inp;
dump grep { shift @$_;1 } map { @$_ } #=deref
reduce { my ($b0,@br)=@$b;$a->[$#$a]->[0] ne $b0 ? [@$a,[@$b]] :
[@$a[0..$#$a-1],[@{$a->[$#$a]},@br]] }
[[@{$sorted[0]}]],@sorted[1..$#sorted];
#dump @inp;
# ------------------------------------------------------
print "\nTie::IxHash variant (first occurence order):\n";
use Tie::IxHash;
tie my %ixh, 'Tie::IxHash';
push @{$ixh{$_->[0]}}, @{$_}[1..$#$_] for @inp;
#or: push @{$h{+shift @$_}},@$_ for clone @inp;
dump values @v;
# ------------------------------------------------------
print "\nTie::IxHash variant2 (first occurence order):\n";
use Tie::IxHash;
tie my %ix2, 'Tie::IxHash';
%ix2=map { my ($k,@r)=@$_; $k => [@{$ix2{$k}||[]},@r]} @inp;
dump values @v;
# ------------------------------------------------------
print "\nData::Pairs variant (first occurence order):\n";
use Data::Pairs;
sub makepairs { my $t=shift; map { { $t => $_ } } @_ }
sub wo_dup { my %e; grep { ! $e{$_}++ } @_ }
my $dp=Data::Pairs->new([map { makepairs @$_ } @inp]);
dump map [$dp->get_values($_)], wo_dup $dp->get_keys;
# ------------------------------------------------------
#use DBI;
#my $dbh = DBI->connect('DBI:RAM:','','',{RaiseError=>1});
#$dbh->func({
# table_name => 'inp',
# col_names => 'id,value',
# data_type => 'ARRAY',
# data_source => [map { distributefirst @$_ } @inp] # nf
#}, 'import' );
#dump $dbh->selectcol_arrayref('SELECT value FROM inp GROUP BY id');