2019-03-18 20:44:09 +01:00
|
|
|
# Working With Arrays
|
|
|
|
|
|
|
|
RETRO offers a number of words for operating on statically sized
|
|
|
|
arrays.
|
|
|
|
|
|
|
|
## Namespace
|
|
|
|
|
2019-04-24 16:02:15 +02:00
|
|
|
The words operating on arrays are kept in an `a:` namespace.
|
2019-03-18 20:44:09 +01:00
|
|
|
|
|
|
|
## Creating Arrays
|
|
|
|
|
|
|
|
The easiest way to create an array is to wrap the values in a
|
|
|
|
`{` and `}` pair:
|
|
|
|
|
|
|
|
```
|
|
|
|
{ #1 #2 #3 #4 }
|
|
|
|
{ 'this 'is 'an 'array 'of 'strings }
|
|
|
|
{ 'this 'is 'a 'mixed 'array #1 #2 #3 }
|
|
|
|
```
|
|
|
|
|
|
|
|
You can also make an array from a quotation which returns
|
2019-04-24 16:02:15 +02:00
|
|
|
values and the number of values to store in the a:
|
2019-03-18 20:44:09 +01:00
|
|
|
|
|
|
|
```
|
2019-04-24 16:02:15 +02:00
|
|
|
[ #1 #2 #3 #3 ] a:counted-results
|
|
|
|
[ #1 #2 #3 #3 ] a:make
|
2019-03-18 20:44:09 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
## Accessing Elements
|
|
|
|
|
2019-05-01 14:18:25 +02:00
|
|
|
You can access a specific value with `a:th` and `fetch` or
|
2019-03-18 20:44:09 +01:00
|
|
|
`store`:
|
|
|
|
|
|
|
|
```
|
2019-05-01 14:18:25 +02:00
|
|
|
{ #1 #2 #3 #4 } #3 a:th fetch
|
2019-03-18 20:44:09 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
## Find The Length
|
|
|
|
|
2019-04-24 16:02:15 +02:00
|
|
|
Use `a:length` to find the size of the array.
|
2019-03-18 20:44:09 +01:00
|
|
|
|
|
|
|
```
|
2019-04-24 16:02:15 +02:00
|
|
|
{ #1 #2 #3 #4 } a:length
|
2019-03-18 20:44:09 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
## Duplicate
|
|
|
|
|
2019-04-24 16:02:15 +02:00
|
|
|
Use `a:dup` to make a copy of an a:
|
2019-03-18 20:44:09 +01:00
|
|
|
|
|
|
|
```
|
2019-04-24 16:02:15 +02:00
|
|
|
{ #1 #2 #3 #4 } a:dup
|
2019-03-18 20:44:09 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
## Filtering
|
|
|
|
|
2019-04-24 16:02:15 +02:00
|
|
|
RETRO provides `a:filter` which extracts matching values
|
2019-03-18 20:44:09 +01:00
|
|
|
from an array. This is used like:
|
|
|
|
|
|
|
|
```
|
2019-04-24 16:02:15 +02:00
|
|
|
{ #1 #2 #3 #4 #5 #6 #7 #8 } [ n:even? ] a:filter
|
2019-03-18 20:44:09 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
The quote will be passed each value in the array and should
|
|
|
|
return TRUE or FALSE. Values that lead to TRUE will be collected
|
|
|
|
into a new array.
|
|
|
|
|
|
|
|
## Mapping
|
|
|
|
|
2019-04-24 16:02:15 +02:00
|
|
|
`a:map` applies a quotation to each item in an array and
|
2019-03-18 20:44:09 +01:00
|
|
|
constructs a new array from the returned values.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```
|
2019-04-24 16:02:15 +02:00
|
|
|
{ #1 #2 #3 } [ #10 * ] a:map
|
2019-03-18 20:44:09 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
## Reduce
|
|
|
|
|
2019-04-24 16:02:15 +02:00
|
|
|
`a:reduce` takes an array, a starting value, and a quote. It
|
2019-03-18 20:44:09 +01:00
|
|
|
executes the quote once for each item in the array, passing the
|
|
|
|
item and the value to the quote. The quote should consume both
|
|
|
|
and return a new value.
|
|
|
|
|
|
|
|
```
|
2019-04-24 16:02:15 +02:00
|
|
|
{ #1 #2 #3 } #0 [ + ] a:reduce
|
2019-03-18 20:44:09 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
## Search
|
|
|
|
|
2019-04-24 16:02:15 +02:00
|
|
|
RETRO provides `a:contains?` and `a:contains-string?`
|
2019-03-18 20:44:09 +01:00
|
|
|
to search an array for a value (either a number or string) and
|
|
|
|
return either TRUE or FALSE.
|
|
|
|
|
|
|
|
```
|
2019-04-24 16:02:15 +02:00
|
|
|
#100 { #1 #2 #3 } a:contains?
|
|
|
|
'test { 'abc 'def 'test 'ghi } a:contains-string?
|
2019-03-18 20:44:09 +01:00
|
|
|
```
|
2019-05-09 19:58:39 +02:00
|
|
|
|
|
|
|
## Implementation
|
|
|
|
|
|
|
|
In memory, an array is a count followed by the values. As an
|
|
|
|
example, if you have an array:
|
|
|
|
|
|
|
|
{ #10 #20 #30 }
|
|
|
|
|
|
|
|
In memory this would be setup as:
|
|
|
|
|
|
|
|
| Offset | Value |
|
|
|
|
| ------ | ----- |
|
|
|
|
| 000 | 3 |
|
|
|
|
| 001 | 10 |
|
|
|
|
| 002 | 20 |
|
|
|
|
| 003 | 30 |
|
|
|
|
|
|
|
|
You can construct one on the fly by keeping a pointer to
|
|
|
|
`here` and using `,` to place the values. E.g.,
|
|
|
|
|
|
|
|
here [ #3 , #10 , #20 , #30 , ] dip
|
|
|
|
|
|
|
|
An example of this can be seen in this excerpt from an example
|
|
|
|
(*example/Primes.forth*):
|
|
|
|
|
|
|
|
:create-set (-a)
|
|
|
|
here #3000 , #2 #3002 [ dup , n:inc ] times drop ;
|