diff --git a/core/assocs/assocs-docs.factor b/core/assocs/assocs-docs.factor index f25c336b54..368f370ec5 100644 --- a/core/assocs/assocs-docs.factor +++ b/core/assocs/assocs-docs.factor @@ -132,7 +132,9 @@ ARTICLE: "assocs-conversions" "Associative mapping conversions" "Combining a sequence of assocs into a single assoc:" { $subsections assoc-combine } "Creating an assoc from key/value sequences:" -{ $subsections zip } +{ $subsections zip zip-as } +"Creating an assoc from key/value sequences and their indices:" +{ $subsections zip-index zip-index-as } "Creating key/value sequences from an assoc:" { $subsections unzip } ; @@ -524,3 +526,46 @@ HELP: zip } } ; { unzip zip } related-words + +HELP: zip-as +{ $values + { "keys" sequence } { "values" sequence } { "exemplar" sequence } + { "obj" "a sequence of key/value pairs of type " { $snippet "exemplar" } } } +{ $description "Combines two sequences pairwise into a single sequence of key/value pairs of type " { $snippet "exemplar" } "." } +{ $notes "Exemplar must be a sequence type; hashtables will not work yet." } +{ $examples + { $example "USING: prettyprint assocs ;" + "{ 1 2 3 } { 4 5 6 } V{ } zip-as ." + "V{ { 1 4 } { 2 5 } { 3 6 } }" + } +} ; + +HELP: zip-index +{ $values + { "values" sequence } + { "alist" "an array of key/value pairs" } +} +{ $examples + "Zip a sequnce with its indices:" + { $example "USING: assocs prettyprint ;" + "{ 100 200 300 } zip-index ." + "{ { 100 0 } { 200 1 } { 300 2 } }" + } +} +{ $description "Zip a sequence with its index and return an associative list where the input sequence is the keys and the indices are the values." } ; + +HELP: zip-index-as +{ $values + { "values" sequence } { "exemplar" sequence } + { "obj" "an array of key/value pairs" } +} +{ $examples + "Zip a sequnce with its indices as a vector:" + { $example "USING: assocs prettyprint ;" + "{ 100 200 300 } V{ } zip-index-as ." + "V{ { 100 0 } { 200 1 } { 300 2 } }" + } +} +{ $description "Zip a sequence with its index and return an associative list of type " { $snippet "exemplar" } " where the input sequence is the keys and the indices are the values." } ; + +{ unzip zip zip-as zip-index zip-index-as } related-words diff --git a/core/assocs/assocs-tests.factor b/core/assocs/assocs-tests.factor index bb91c79928..62218c8bdf 100644 --- a/core/assocs/assocs-tests.factor +++ b/core/assocs/assocs-tests.factor @@ -211,4 +211,42 @@ unit-test { { f 2 } } } [ { { 1 f } { f 2 } } sift-values -] unit-test \ No newline at end of file +] unit-test + +! zip, zip-as +{ + { { 1 4 } { 2 5 } { 3 6 } } +} [ { 1 2 3 } { 4 5 6 } zip ] unit-test + +{ + { { 1 4 } { 2 5 } { 3 6 } } +} [ { 1 2 3 } { 4 5 6 } { } zip-as ] unit-test + +{ + { { 1 4 } { 2 5 } { 3 6 } } +} [ B{ 1 2 3 } { 4 5 6 } { } zip-as ] unit-test + +{ + V{ { 1 4 } { 2 5 } { 3 6 } } +} [ { 1 2 3 } { 4 5 6 } V{ } zip-as ] unit-test + +{ + V{ { 1 4 } { 2 5 } { 3 6 } } +} [ BV{ 1 2 3 } BV{ 4 5 6 } V{ } zip-as ] unit-test + +! zip-index, zip-index-as +{ + { { 11 0 } { 22 1 } { 33 2 } } +} [ { 11 22 33 } zip-index ] unit-test + +{ + { { 11 0 } { 22 1 } { 33 2 } } +} [ { 11 22 33 } { } zip-index-as ] unit-test + +{ + { { 11 0 } { 22 1 } { 33 2 } } +} [ V{ 11 22 33 } { } zip-index-as ] unit-test + +{ + V{ { 11 0 } { 22 1 } { 33 2 } } +} [ { 11 22 33 } V{ } zip-index-as ] unit-test diff --git a/core/assocs/assocs.factor b/core/assocs/assocs.factor index ed43d9325f..7db91548bd 100644 --- a/core/assocs/assocs.factor +++ b/core/assocs/assocs.factor @@ -198,8 +198,17 @@ M: assoc value-at* swap [ = nip ] curry assoc-find nip ; : push-at ( value key assoc -- ) [ ?push ] change-at ; +: zip-as ( keys values exemplar -- obj ) + [ [ 2array ] ] dip 2map-as ; inline + : zip ( keys values -- alist ) - [ 2array ] { } 2map-as ; inline + { } zip-as ; inline + +: zip-index-as ( values exemplar -- obj ) + [ [ 2array ] ] dip map-index-as ; inline + +: zip-index ( values -- alist ) + { } zip-index-as ; inline : unzip ( assoc -- keys values ) dup assoc-empty? [ drop { } { } ] [ >alist flip first2 ] if ; diff --git a/core/sequences/sequences-docs.factor b/core/sequences/sequences-docs.factor index 80ec15cfbf..1e85d4efeb 100644 --- a/core/sequences/sequences-docs.factor +++ b/core/sequences/sequences-docs.factor @@ -374,6 +374,16 @@ HELP: map-index "{ { 10 0 } { 20 1 } { 30 2 } }" } } ; +HELP: map-index-as +{ $values + { "seq" sequence } { "quot" { $quotation ( ... elt index -- ... newelt ) } } { "exemplar" sequence } { "newseq" sequence } } +{ $description "Calls the quotation with the element of the sequence and its index on the stack, with the index on the top of the stack. Collects the outputs of the quotation and outputs them in a sequence of the same type as the " { $snippet "exemplar" } " sequence." } +{ $examples { $example "USING: arrays sequences prettyprint ;" +"{ 10 20 30 } [ 2array ] V{ } map-index-as ." +"V{ { 10 0 } { 20 1 } { 30 2 } }" +} } ; +{ map-index map-index-as } related-words + HELP: change-nth { $values { "i" "a non-negative integer" } { "seq" "a mutable sequence" } { "quot" { $quotation ( ..a elt -- ..b newelt ) } } } { $description "Applies the quotation to the " { $snippet "i" } "th element of the sequence, storing the result back into the sequence." } @@ -1681,6 +1691,7 @@ ARTICLE: "sequences-combinators" "Sequence combinators" map map-as map-index + map-index-as map-reduce accumulate accumulate-as diff --git a/core/sequences/sequences-tests.factor b/core/sequences/sequences-tests.factor index d339f60b8d..5b05b4ef30 100644 --- a/core/sequences/sequences-tests.factor +++ b/core/sequences/sequences-tests.factor @@ -386,3 +386,19 @@ USE: make { { } } [ 0 0 >array ] unit-test { { 0 } } [ 1 0 >array ] unit-test { { 0 0 0 } } [ 3 0 >array ] unit-test + +{ + { 11 23 35 } +} [ { 11 22 33 } [ + ] map-index ] unit-test + +{ + V{ 11 23 35 } +} [ { 11 22 33 } [ + ] V{ } map-index-as ] unit-test + +{ + B{ 11 23 35 } +} [ { 11 22 33 } [ + ] B{ } map-index-as ] unit-test + +{ + BV{ 11 23 35 } +} [ { 11 22 33 } [ + ] BV{ } map-index-as ] unit-test diff --git a/core/sequences/sequences.factor b/core/sequences/sequences.factor index b3f458bca4..0cb5345134 100644 --- a/core/sequences/sequences.factor +++ b/core/sequences/sequences.factor @@ -578,8 +578,11 @@ PRIVATE> 3bi ] if ; inline +: map-index-as ( ... seq quot: ( ... elt index -- ... newelt ) exemplar -- ... newseq ) + [ dup length iota ] 2dip 2map-as ; inline + : map-index ( ... seq quot: ( ... elt index -- ... newelt ) -- ... newseq ) - [ dup length iota ] dip 2map ; inline + { } map-index-as ; inline : reduce-index ( ... seq identity quot: ( ... prev elt index -- ... next ) -- ... result ) swapd each-index ; inline