Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement Hash.(classify|categorize), as well as other mapper types
  • Loading branch information
lizmat committed Jun 15, 2013
1 parent 42ef7be commit d3ae978
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 22 deletions.
8 changes: 6 additions & 2 deletions src/core/Any.pm
Expand Up @@ -14,7 +14,8 @@ my class Any {
method eager() { nqp::p6list(nqp::list(self), List, Bool::True).eager }
method elems() { self.list.elems }
method end() { self.list.end }
method classify(&t) { self.list.classify(&t) }
method classify($test) { {}.classify( $test, self.list ) }
method categorize($test) { {}.categorize( $test, self.list ) }
method uniq() { self.list.uniq }
method infinite() { Mu }
method flat() { nqp::p6list(nqp::list(self), List, Bool::True) }
Expand Down Expand Up @@ -706,7 +707,10 @@ proto end(|) { * }
multi end($a) { $a.end }

proto classify(|) { * }
multi classify(&test, *@items) { @items.classify(&test) }
multi classify( $test, *@items ) { {}.classify( $test, @items ) }

proto categorize(|) { * }
multi categorize( $test, *@items ) { {}.categorize( $test, @items ) }

proto uniq(|) { * }
multi uniq(*@values) { @values.uniq }
Expand Down
55 changes: 55 additions & 0 deletions src/core/Hash.pm
Expand Up @@ -103,6 +103,61 @@ my class Hash {
self
}

proto method classify(|) { * }
multi method classify( &test, *@list ) {
fail 'Cannot .classify an infinite list' if @list.infinite;
for @list {
self{test $_}.push: $_;
}
self;
}
multi method classify( %test, *@list ) {
fail 'Cannot .classify an infinite list' if @list.infinite;
for @list {
self{ %test{$_} }.push: $_;
}
self;
}
multi method classify( @test, *@list ) {
fail 'Cannot .classify an infinite list' if @list.infinite;
for @list {
self{ @test[$_] }.push: $_;
}
self;
}

proto method categorize(|) { * }
multi method categorize( &test, *@list ) {
fail 'Cannot .categorize an infinite list' if @list.infinite;
for @list {
my @k = test $_;
for @k -> $k {
self{$k}.push: $_;
}
}
self;
}
multi method categorize( %test, *@list ) {
fail 'Cannot .categorize an infinite list' if @list.infinite;
for @list {
my @k = %test{$_};
for @k -> $k {
self{$k}.push: $_;
}
}
self;
}
multi method categorize( @test, *@list ) {
fail 'Cannot .categorize an infinite list' if @list.infinite;
for @list {
my @k = @test[$_];
for @k -> $k {
self{$k}.push: $_;
}
}
self;
}

# push a value onto a hash slot, constructing an array if necessary
method !_push_construct(Mu $key, Mu $value) {
if self.exists($key) {
Expand Down
22 changes: 2 additions & 20 deletions src/core/List.pm
Expand Up @@ -318,26 +318,9 @@ my class List does Positional {
$tpos >= +$tseq;
}

method classify(&test) {
fail 'Cannot .classify an infinite list' if self.infinite; # MMD?
my %result;
for @.list {
%result{test $_}.push: $_;
}
%result;
}
method classify ($test) { {}.classify( $test, @.list ) }

method categorize(&test) {
fail 'Cannot .categorize an infinite list' if self.infinite; #MMD?
my %result;
for @.list {
my @k = test $_;
for @k -> $k {
%result{$k}.push: $_;
}
}
%result.pairs;
}
method categorize ($test) { {}.categorize( $test, @.list ) }

# This needs a way of taking a user-defined comparison
# specifier, but AFAIK nothing has been spec'd yet.
Expand Down Expand Up @@ -457,7 +440,6 @@ multi sub push(\a, *@elems) { a.push: @elems }
sub reverse(*@a) { @a.reverse }
sub rotate(@a, Int $n = 1) { @a.rotate($n) }
sub reduce (&with, *@list) { @list.reduce(&with) }
sub categorize(&mapper, *@a){ @a.categorize(&mapper)}
sub splice(@arr, $offset = 0, $size?, *@values) {
@arr.splice($offset, $size, @values)
}

0 comments on commit d3ae978

Please sign in to comment.