]> gitweb.factorcode.org Git - factor.git/commitdiff
Add assoc-partition combinator, and re-implement assoc-filter in a more straightforwa...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 27 Jan 2009 05:19:49 +0000 (23:19 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 27 Jan 2009 05:19:49 +0000 (23:19 -0600)
core/assocs/assocs-docs.factor
core/assocs/assocs-tests.factor
core/assocs/assocs.factor

index 627d4aeb80190e3f3c3cdd87de15202cecadab77..e9269373b0fcf8717f0f8e200d8d001bbb6aff2c 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (C) 2007 Daniel Ehrenberg, Slava Pestov, and Doug Coleman
+! Copyright (C) 2007, 2009 Daniel Ehrenberg, Slava Pestov, and Doug Coleman
 ! See http://factorcode.org/license.txt for BSD license.
 USING: help.markup help.syntax kernel sequences
-sequences.private namespaces math quotations ;
+sequences.private namespaces math quotations assocs.private ;
 IN: assocs
 
 ARTICLE: "alists" "Association lists"
@@ -113,7 +113,6 @@ $nl
 { $subsection assoc-each }
 { $subsection assoc-find }
 { $subsection assoc-map }
-{ $subsection assoc-push-if }
 { $subsection assoc-filter }
 { $subsection assoc-filter-as }
 { $subsection assoc-contains? }
@@ -122,10 +121,7 @@ $nl
 { $subsection cache }
 { $subsection map>assoc }
 { $subsection assoc>map }
-{ $subsection assoc-map-as }
-{ $subsection search-alist }
-"Utility word:"
-{ $subsection assoc-pusher } ;
+{ $subsection assoc-map-as } ;
 
 ARTICLE: "assocs" "Associative mapping operations"
 "An " { $emphasis "associative mapping" } ", abbreviated " { $emphasis "assoc" } ", is a collection of key/value pairs which provides efficient lookup and storage indexed by key."
@@ -225,10 +221,6 @@ HELP: assoc-map
 
 { assoc-map assoc-map-as } related-words
 
-HELP: assoc-push-if
-{ $values { "accum" "a resizable mutable sequence" } { "quot" { $quotation "( key value -- ? )" } } { "key" object } { "value" object } }
-{ $description "If the quotation yields true when applied to the key/value pair, adds the key/value pair at the end of " { $snippet "accum" } "." } ;
-
 HELP: assoc-filter
 { $values { "assoc" assoc } { "quot" { $quotation "( key value -- ? )" } } { "subassoc" "a new assoc" } }
 { $description "Outputs an assoc of the same type as " { $snippet "assoc" } " consisting of all entries for which the predicate quotation yields true." } ;
@@ -388,18 +380,6 @@ HELP: assoc-map-as
 { $description "Applies the quotation to each entry in the input assoc and collects the results in a new assoc of the stame type as the exemplar." }
 { $examples { $example "USING: prettyprint assocs hashtables math ;" " H{ { 1 2 } { 3 4 } } [ sq ] { } assoc-map-as ." "{ { 1 4 } { 3 16 } }" } } ;
 
-HELP: assoc-pusher
-{ $values
-     { "quot" "a predicate quotation" }
-     { "quot'" quotation } { "accum" assoc } }
-{ $description "Creates a new " { $snippet "assoc" } " to accumulate the key/value pairs which return true for a predicate.  Returns a new quotation which accepts a pair of object to be tested and stored in the accumulator if the test yields true. The accumulator is left on the stack for convenience." }
-{ $example "! Find only the pairs that sum to 5:" "USING: prettyprint assocs math kernel ;"
-           "{ { 1 2 } { 2 3 } { 3 4 } } [ + 5 = ] assoc-pusher [ assoc-each ] dip ."
-           "V{ { 2 3 } }"
-}
-{ $notes "Used to implement the " { $link assoc-filter } " word." } ;
-
-
 HELP: extract-keys
 { $values
      { "seq" sequence } { "assoc" assoc }
index ac82da7b9be495ab478a9db72523c344ab7cda96..5617888148ede69c4928ff7e98a58bf1d25d434b 100644 (file)
@@ -129,4 +129,13 @@ unit-test
 
 [ "x" ] [
     "a" H{ { "a" "x" } } at-default
+] unit-test
+
+[ H{ { "b" [ 2 ] } { "d" [ 4 ] } } H{ { "a" [ 1 ] } { "c" [ 3 ] } } ] [
+    H{
+        { "a" [ 1 ] }
+        { "b" [ 2 ] }
+        { "c" [ 3 ] }
+        { "d" [ 4 ] }
+    } [ nip first even? ] assoc-partition
 ] unit-test
\ No newline at end of file
index a2eb2d25ec639611ccaf80cf73892808d973e23c..b074fa1b9269924ec4ec44140fda26e0bef4ccd5 100644 (file)
@@ -7,22 +7,39 @@ IN: assocs
 MIXIN: assoc
 
 GENERIC: at* ( key assoc -- value/f ? )
+GENERIC: value-at* ( value assoc -- key/f ? )
 GENERIC: set-at ( value key assoc -- )
 GENERIC: new-assoc ( capacity exemplar -- newassoc )
 GENERIC: delete-at ( key assoc -- )
 GENERIC: clear-assoc ( assoc -- )
 GENERIC: assoc-size ( assoc -- n )
 GENERIC: assoc-like ( assoc exemplar -- newassoc )
+GENERIC: assoc-clone-like ( assoc exemplar -- newassoc )
+GENERIC: >alist ( assoc -- newassoc )
 
 M: assoc assoc-like drop ;
 
-GENERIC: assoc-clone-like ( assoc exemplar -- newassoc )
-
-GENERIC: >alist ( assoc -- newassoc )
+<PRIVATE
 
 : (assoc-each) ( assoc quot -- seq quot' )
     [ >alist ] dip [ first2 ] prepose ; inline
 
+: (assoc-stack) ( key i seq -- value )
+    over 0 < [
+        3drop f
+    ] [
+        3dup nth-unsafe at*
+        [ [ 3drop ] dip ] [ drop [ 1- ] dip (assoc-stack) ] if
+    ] if ; inline recursive
+
+: search-alist ( key alist -- pair/f i/f )
+    [ first = ] with find swap ; inline
+
+: substituter ( assoc -- quot )
+    [ dupd at* [ nip ] [ drop ] if ] curry ; inline
+
+PRIVATE>
+
 : assoc-find ( assoc quot -- key value ? )
     (assoc-each) find swap [ first2 t ] [ drop f f f ] if ; inline
 
@@ -40,18 +57,16 @@ GENERIC: >alist ( assoc -- newassoc )
 : assoc-map ( assoc quot -- newassoc )
     over assoc-map-as ; inline
 
-: assoc-push-if ( key value quot accum -- )
-    [ 2keep ] dip [ [ 2array ] dip push ] 3curry when ; inline
-
-: assoc-pusher ( quot -- quot' accum )
-    V{ } clone [ [ assoc-push-if ] 2curry ] keep ; inline
-
 : assoc-filter-as ( assoc quot exemplar -- subassoc )
-    [ assoc-pusher [ assoc-each ] dip ] dip assoc-like ; inline
+    [ (assoc-each) filter ] dip assoc-like ; inline
 
 : assoc-filter ( assoc quot -- subassoc )
     over assoc-filter-as ; inline
 
+: assoc-partition ( assoc quot -- true-assoc false-assoc )
+    [ (assoc-each) partition ] [ drop ] 2bi
+    tuck [ assoc-like ] 2bi@ ; inline
+
 : assoc-contains? ( assoc quot -- ? )
     assoc-find 2nip ; inline
 
@@ -65,7 +80,7 @@ GENERIC: >alist ( assoc -- newassoc )
     2dup at* [ 2nip ] [ 2drop ] if ; inline
 
 M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
-    over assoc-size swap new-assoc
+    [ dup assoc-size ] dip new-assoc
     [ [ swapd set-at ] curry assoc-each ] keep ;
 
 : keys ( assoc -- keys )
@@ -81,15 +96,7 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
     [ delete-at* ] keep [ swapd set-at ] curry [ 2drop ] if ;
 
 : assoc-empty? ( assoc -- ? )
-    assoc-size zero? ;
-
-: (assoc-stack) ( key i seq -- value )
-    over 0 < [
-        3drop f
-    ] [
-        3dup nth-unsafe at*
-        [ [ 3drop ] dip ] [ drop [ 1- ] dip (assoc-stack) ] if
-    ] if ; inline recursive
+    assoc-size 0 = ;
 
 : assoc-stack ( key seq -- value )
     [ length 1- ] keep (assoc-stack) ; flushable
@@ -101,9 +108,7 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
     [ assoc-subset? ] [ swap assoc-subset? ] 2bi and ;
 
 : assoc-hashcode ( n assoc -- code )
-    [
-        [ over ] dip hashcode* 2/ [ dupd hashcode* ] dip bitxor
-    ] { } assoc>map hashcode* ;
+    >alist hashcode* ;
 
 : assoc-intersect ( assoc1 assoc2 -- intersection )
     swap [ nip key? ] curry assoc-filter ;
@@ -124,9 +129,6 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
 : remove-all ( assoc seq -- subseq )
     swap [ key? not ] curry filter ;
 
-: substituter ( assoc -- quot )
-    [ dupd at* [ nip ] [ drop ] if ] curry ; inline
-
 : substitute-here ( seq assoc -- )
     substituter change-each ;
 
@@ -155,8 +157,6 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
 : extract-keys ( seq assoc -- subassoc )
     [ [ dupd at ] curry ] keep map>assoc ;
 
-GENERIC: value-at* ( value assoc -- key/f ? )
-
 M: assoc value-at* swap [ = nip ] curry assoc-find nip ;
 
 : value-at ( value assoc -- key/f ) value-at* drop ;
@@ -172,9 +172,6 @@ M: assoc value-at* swap [ = nip ] curry assoc-find nip ;
 : unzip ( assoc -- keys values )
     dup assoc-empty? [ drop { } { } ] [ >alist flip first2 ] if ;
 
-: search-alist ( key alist -- pair/f i/f )
-    [ first = ] with find swap ; inline
-
 M: sequence at*
     search-alist [ second t ] [ f ] if ;