# SRFI 133 - Vector Library

The `(srfi 133)`

provides a vector library.

See the SRFI document for more information.

## Constructors

`vector-unfold`

`vector-unfold-right`

`vector-reverse-copy`

`vector-concatenate`

`vector-append-subvectors`

## Predicates

## Iteration

`vector-fold`

`vector-fold-right`

`vector-map!`

`vector-count`

`vector-cumulate`

## Searching

`vector-index`

`vector-index-right`

`vector-skip`

`vector-skip-right`

`vector-binary-search`

`vector-any`

`vector-every`

`vector-partition`

## Mutators

`vector-swap!`

`vector-reverse!`

`vector-reverse-copy!`

`vector-unfold!`

`vector-unfold-right!`

## Conversion

`reverse-vector->list`

`reverse-list->vector`

# vector-unfold

```
(vector-unfold f length initial-seed ...) -> vector
```

The fundamental vector constructor. Creates a vector whose length is `length`

and iterates across each index `k`

between `0`

and `length`

, applying `f`

at each iteration to the current index and current seeds, in that order, to receive n + 1 values: first, the element to put in the kth slot of the new vector and n new seeds for the next iteration. It is an error for the number of seeds to vary between iterations. Note that the termination condition is different from the `unfold`

procedure of SRFI 1.

Examples:

```
(vector-unfold (λ (i x) (values x (- x 1)))
10 0)
#(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)
```

Construct a vector of the sequence of integers in the range [0,n).

```
(vector-unfold values n)
#(0 1 2 ... n-2 n-1)
```

Copy vector.

```
(vector-unfold (λ (i) (vector-ref vector i))
(vector-length vector))
```

# vector-unfold-right

```
(vector-unfold-right f length initial-seed ...) -> vector
```

Like `vector-unfold`

, but it uses `f`

to generate elements from right-to-left, rather than left-to-right. The first `index`

used is `length - 1`

. Note that the termination condition is different from the `unfold-right`

procedure of SRFI 1.

Examples:

Construct a vector of pairs of non-negative integers whose values sum to 4.

```
(vector-unfold-right (λ (i x) (values (cons i x) (+ x 1))) 5 0)
#((0 . 4) (1 . 3) (2 . 2) (3 . 1) (4 . 0))
```

Reverse vector.

```
(vector-unfold-right (λ (i x) (values (vector-ref vector x) (+ x 1)))
(vector-length vector)
0)
```

# vector-reverse-copy

```
(vector-reverse-copy vec [start [end]]) -> vector
```

Like `vector-copy`

, but it copies the elements in the reverse order from `vec`

.

Example:

```
(vector-reverse-copy '#(5 4 3 2 1 0) 1 5)
#(1 2 3 4)
```

# vector-concatenate

```
(vector-concatenate list-of-vectors) -> vector
```

Appends each vector in `list-of-vectors`

. This is equivalent to:

```
(apply vector-append list-of-vectors)
```

However, it may be implemented better.

Example:

```
(vector-concatenate '(#(a b) #(c d)))
#(a b c d)
```

# vector-append-subvectors

```
(vector-append-subvectors [vec start end] ...) -> vector
```

Returns a vector that contains every element of each `vec`

from `start`

to `end`

in the specified order. This procedure is a generalization of `vector-append`

.

Example:

```
(vector-append-subvectors '#(a b c d e) 0 2 '#(f g h i j) 2 4)
#(a b h i)
```

# vector-empty?

```
(vector-empty? vec) -> boolean
```

Returns `#t`

if `vec`

is empty, i.e. its length is `0`

, and `#f`

if not.

# vector=

```
(vector= elt=? vec ...) -> boolean
```

Vector structure comparator, generalized across user-specified element comparators. Vectors `a`

and `b`

are considered equal by `vector=`

iff their lengths are the same, and for each respective element `Ea`

and `Eb`

, `(elt=? Ea Eb)`

returns a true value. `Elt=?`

is always applied to two arguments.

If there are only zero or one vector arguments, `#t`

is automatically returned. The dynamic order in which comparisons of elements and of vectors are performed is left completely unspecified; do not rely on a particular order.

Examples:

```
(vector= eq? '#(a b c d) '#(a b c d))
#t
(vector= eq? '#(a b c d) '#(a b d c))
#f
(vector= = '#(1 2 3 4 5) '#(1 2 3 4))
#f
(vector= = '#(1 2 3 4) '#(1 2 3 4))
#t
```

The two trivial cases.

```
(vector= eq?)
#t
(vector= eq? '#(a))
#t
```

Note the fact that we don’t use vector literals in the next two. It is unspecified whether or not literal vectors with the same external representation are `eq?`

.

```
(vector= eq? (vector (vector 'a)) (vector (vector 'a)))
#f
(vector= equal? (vector (vector 'a)) (vector (vector 'a)))
#t
```

# vector-fold

```
(vector-fold kons knil vec1 vec2 ...) -> value
```

The fundamental vector iterator. `Kons`

is iterated over each value in all of the vectors, stopping at the end of the shortest; `kons`

is applied as `(kons state (vector-ref vec1 i) (vector-ref vec2 i) ...)`

where `state`

is the current state value. The current state value begins with `knil`

, and becomes whatever `kons`

returned on the previous iteration, and `i`

is the current index.

The iteration is strictly left-to-right.

Examples:

Find the longest string’s length in `vector-of-strings`

.

```
(vector-fold (λ (len str) (max (string-length str) len))
0 vector-of-strings)
```

Produce a list of the reversed elements of `vec`

.

```
(vector-fold (λ (tail elt) (cons elt tail))
'() vec)
```

Count the number of even numbers in `vec`

.

```
(vector-fold (λ (counter n)
(if (even? n) (+ counter 1) counter))
0 vec)
```

# vector-fold-right

```
(vector-fold-right kons knil vec1 vec2 ...) -> value
```

Similar to `vector-fold`

, but it iterates right to left instead of left to right.

Example:

Convert a vector to a list.

```
(vector-fold-right (λ (tail elt) (cons elt tail))
'() '#(a b c d))
(a b c d)
```

# vector-map!

```
(vector-map! f vec1 vec2 ...) -> unspecified
```

Similar to `vector-map`

, but rather than mapping the new elements into a new vector, the new mapped elements are destructively inserted into `vec1`

. Again, the dynamic order of application of `f`

is unspecified, so it is dangerous for `f`

to apply either `vector-ref`

or `vector-set!`

to `vec1`

in `f`

.

# vector-count

```
(vector-count pred? vec1 vec2 ...) -> exact nonnegative integer
```

Counts the number of parallel elements in the vectors that satisfy `pred?`

, which is applied, for each index `i`

in the range [0, length) where `length`

is the length of the smallest vector argument, to each parallel element in the vectors, in order.

Examples:

```
(vector-count even? '#(3 1 4 1 5 9 2 5 6))
3
(vector-count < '#(1 3 6 9) '#(2 4 6 8 10 12))
2
```

# vector-cumulate

```
(vector-cumulate f knil vec) -> vector
```

Returns a newly allocated vector `new`

with the same length as `vec`

. Each element `i`

of `new`

is set to the result of invoking `f`

on `newi-1`

and `veci`

, except that for the first call on `f`

, the first argument is `knil`

. The new vector is returned.

Example:

```
(vector-cumulate + 0 '#(3 1 4 1 5 9 2 5 6))
#(3 4 8 9 14 23 25 30 36)
```

# vector-index

```
(vector-index pred? vec1 vec2 ...) -> exact nonnegative integer or #f
```

Finds & returns the index of the first elements in `vec1 vec2 ...`

that satisfy `pred?`

. If no matching element is found by the end of the shortest vector, `#f`

is returned.

Examples:

```
(vector-index even? '#(3 1 4 1 5 9))
2
(vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
1
(vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
#f
```

# vector-index-right

```
(vector-index-right pred? vec1 vec2 ...) -> exact nonnegative integer or #f
```

Like `vector-index`

, but it searches right-to-left, rather than left-to-right, and all of the vectors must have the same length.

# vector-skip

```
(vector-skip pred? vec1 vec2 ...) -> exact nonnegative integer or #f
```

Finds & returns the index of the first elements in `vec1 vec2 ...`

that do not satisfy `pred?`

. If all the values in the vectors satisfy `pred?`

until the end of the shortest vector, this returns `#f`

. This is equivalent to:

```
(vector-index (λ (x1 x2 ...) (not (pred? x1 x1 ...)))
vec1 vec2 ...)
```

Example:

```
(vector-skip number? '#(1 2 a b 3 4 c d))
2
```

# vector-skip-right

```
(vector-skip-right pred? vec1 vec2 ...) -> exact nonnegative integer or #f
```

Like `vector-skip`

, but it searches for a non-matching element right-to-left, rather than left-to-right, and it is an error if all of the vectors do not have the same length. This is equivalent to:

```
(vector-index-right (λ (x1 x2 ...) (not (pred? x1 x1 ...)))
vec1 vec2 ...)
```

# vector-binary-search

```
(vector-binary-search vec value cmp) -> exact nonnegative integer or #f
```

Similar to `vector-index`

and `vector-index-right`

, but instead of searching left to right or right to left, this performs a binary search. If there is more than one element of `vec`

that matches value in the sense of `cmp`

, `vector-binary-search`

may return the index of any of them.

`cmp`

should be a procedure of two arguments and return a negative integer, which indicates that its first argument is less than its second, zero, which indicates that they are equal, or a positive integer, which indicates that the first argument is greater than the second argument. An example `cmp`

might be:

```
(lambdaλ (char1 char2)
(cond ((char<? char1 char2) -1)
((char=? char1 char2) 0)
(else 1)))
```

# vector-any

```
(vector-any pred? vec1 vec2 ...) -> value or #f
```

Finds the first set of elements in parallel from `vec1 vec2 ...`

for which `pred?`

returns a true value. If such a parallel set of elements exists, `vector-any`

returns the value that `pred?`

returned for that set of elements. The iteration is strictly left-to-right.

# vector-every

```
(vector-every pred? vec1 vec2 ...) -> value or #f
```

If, for every index `i`

between `0`

and the length of the shortest vector argument, the set of elements `(vector-ref vec1 i) (vector-ref vec2 i) ...`

satisfies `pred?`

, `vector-every`

returns the value that `pred?`

returned for the last set of elements, at the last index of the shortest vector. The iteration is strictly left-to-right.

# vector-partition

```
(vector-partition pred? vec) -> vector and integer
```

A vector the same size as `vec`

is newly allocated and filled with all the elements of `vec`

that satisfy `pred?`

in their original order followed by all the elements that do not satisfy `pred?`

, also in their original order.

Two values are returned, the newly allocated vector and the index of the leftmost element that does not satisfy `pred?`

.

# vector-swap!

```
(vector-swap! vec i j) -> unspecified
```

Swaps or exchanges the values of the locations in `vec`

at `i`

& `j`

.

# vector-reverse!

```
(vector-reverse! vec [start [end]]) -> unspecified
```

Destructively reverses the contents of the sequence of locations in `vec`

between `start`

and `end`

. Start defaults to `0`

and `end`

defaults to the length of `vec`

. Note that this does not deeply reverse.

# vector-reverse-copy!

```
(vector-reverse-copy! to at from [start [end]]) -> unspecified
```

Like `vector-copy!`

, but the elements appear in to in reverse order.

# vector-unfold!

```
(vector-unfold! f vec start end initial-seed ...) -> unspecified
```

Like `vector-unfold`

, but the elements are copied into the vector `vec`

starting at element `start`

rather than into a newly allocated vector. Terminates when `end-start`

elements have been generated.

# vector-unfold-right!

```
(vector-unfold-right! f vec start end initial-seed ...) -> unspecified
```

`Like `

vector-unfold!`, but the elements are copied in reverse order into the vector `

vec` starting at the index preceding `

end`.

# reverse-vector->list

```
(reverse-vector->list vec [start [end]]) -> proper-list
```

Like `vector->list`

, but the resulting list contains the elements in reverse of `vec`

.

# reverse-list->vector

```
(reverse-list->vector proper-list) -> vector
```

Like `list->vector`

, but the resulting vector contains the elements in reverse of `proper-list`

.