# (lispkit vector)

Vectors are heterogeneous data structures whose elements are indexed by a range of integers. A vector typically occupies less space than a list of the same length, and a randomly chosen element can be accessed in constant time vs. linear time for lists.

The

*length*of a vector is the number of elements that it contains. This number is a non-negative integer that is fixed when the vector is created. The valid indexes of a vector are the exact, non-negative integers less than the length of the vector. The first element in a vector is indexed by zero, and the last element is indexed by one less than the length of the vector.Two vectors are

`equal?`

if they have the same length, and if the values in corresponding slots of the vectors are `equal?`

.A vector can be

*mutable*or*immutable*. Trying to change the state of an*immutable vector*, e.g. via`vector-set!`

will result in an error being raised.Vectors are written using the notation

`#(obj ...)`

. For example, a vector of length 3 containing the number zero in element 0, the list (1 2 3 4) in element 1, and the string "Lisp" in element 2 can be written as follows: `#(0 (1 2 3 4) "Lisp")`

.Vector constants are self-evaluating, so they do not need to be quoted in programs. Vector constants, i.e. vectors created with a vector literal, are

*immutable*.LispKit also supports

*growable vectors*via library`(lispkit gvector)`

. As opposed to regular vectors, a growable vector does not have a fixed size and supports adding and removing elements. While a growable vector does not satisfay the `vector?`

predicate, this library also accepts growable vectors as parameters whenever a vector is expected. Use predicate `mutable-vector?`

for determining whether a vector is either a regular mutable vector or a growable vector.**(vector?**

*obj***)**

Returns

`#t`

if *obj*is a regular vector; otherwise returns`#f`

. This function returns `#f`

for growable vectors; see library `(lispkit gvector)`

.**(mutable-vector?**

*obj***)**

Returns

`#t`

if *obj*is either a mutable regular vector or a growable vector (see library`(lispkit gvector)`

); otherwise returns `#f`

.**(immutable-vector?**

*obj***)**

Returns

`#t`

if *obj*is an immutable vector; otherwise returns`#f`

.**(vector=**

*eql vector ...***)**

Procedure

`vector=`

is a generic comparator for vectors. Vectors *a*and*b*are considered equal by`vector=`

if their lengths are the same, and for each respective elements *ai*and*bi*,`(eql ai bi)`

evaluates to true. *eql*is always applied to two arguments.If there are only zero or one vector argument,

`#t`

is automatically returned. The dynamic order in which comparisons of elements and of vectors are performed is unspecified.(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.0 2.0 3.0 4.0)) ⇒ #t

(vector= eq?) ⇒ #t

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

**(make-vector**

*k***)**

**(make-vector**

*k fill***)**

Returns a newly allocated vector of

*k*elements. If a second argument is given, then each element is initialized to*fill*. Otherwise the initial contents of each element is unspecified.**(vector**

*obj ...***)**

Returns a newly allocated mutable vector whose elements contain the given arguments. It is analogous to

`list`

.(vector ’a ’b ’c) ⇒ #(a b c)

**(immutable-vector**

*obj ...***)**

Returns a newly allocated immutable vector whose elements contain the given arguments in the given order.

**(list->vector**

*list***)**

The

`list->vector`

procedure returns a newly created mutable vector initialized to the elements of the list *list*in the order of the list.(list->vector ’(a b c)) ⇒ #(a b c)

**(list->immutable-vector**

*list***)**

The

`list->vector`

procedure returns a newly created immutable vector initialized to the elements of the list *list*in the order of the list.**(string->vector**

*str***)**

**(string->vector**

*str start***)**

**(string->vector**

*str start end***)**

The

`string->vector`

procedure returns a newly created mutable vector initialized to the elements of the string *str*between*start*and*end*(i.e. including all characters from index*start*to index*end*-1).(string->vector "ABC") ⇒ #(#\A #\B #\C)

**(vector-copy**

*vector***)**

**(vector-copy**

*vector mutable***)**

**(vector-copy**

*vector start***)**

**(vector-copy**

*vector start end***)**

**(vector-copy**

*vector start end mutable***)**

Returns a newly allocated copy of the elements of the given vector between

*start*and*end*, but excluding the element at index*end*. The elements of the new vector are the same (in the sense of`eqv?`

) as the elements of the old.*mutable*is a boolean argument. If it is set to

`#f`

, an immutable copy of *vector*will be created. The type of the second argument of

`vector-copy`

is used to disambiguate between the second and third version of the function. An exact integer will always be interpreted as *start*, a boolean value will always be interpreted as

*mutable*.

(define a #(1 8 2 8)) ; a may be immutable

(define b (vector-copy a)) ; creates a mutable copy of a

(vector-set! b 0 3) ; b is mutable

b ⇒ #(3 8 2 8)

(define c (vector-copy a #f)) ; creates an immutable copy of a

(vector-set! c 0 3) ⇒ error ; error, since c is immutable

(define d (vector-copy b 1 3))

d ⇒ #(8 2)

**(vector-append**

*vector ...***)**

Returns a newly allocated mutable vector whose elements are the concatenation of the elements of the given vectors.

(vector-append #(a b c) #(d e f)) ⇒ #(a b c d e f)

**(vector-concatenate**

*vector xs***)**

Returns a newly allocated mutable vector whose elements are the concatenation of the elements of the vectors in

*xs*.*xs*is a proper list of vectors.(vector-concatenate '(#(a b c) #(d) #(e f))) ⇒ #(a b c d e f)

**(vector-map**

*f vector1 vector2 ...***)**

Constructs a new mutable vector of the shortest size of the vector arguments

*vector1*,*vector2*, etc. Each element at index*i*of the new vector is mapped from the old vectors by`(f (vector-ref vector1 i) (vector-ref vector2 i) ...)`

. The dynamic order of the application of f is unspecified.(vector-map + #(1 2 3 4 5) #(10 20 30 40)) ⇒ #(11 22 33 44)

**(vector-map/index**

*f vector1 vector2 ...***)**

Constructs a new mutable vector of the shortest size of the vector arguments

*vector1*,*vector2*, etc. Each element at index*i*of the new vector is mapped from the old vectors by`(f i (vector-ref vector1 i) (vector-ref vector2 i) ...)`

. The dynamic order of the application of f is unspecified.(vector-map/index (lambda (i x y) (cons i (+ x y))) #(1 2 3) #(10 20 30))

⇒ #((0 . 11) (1 . 22) (2 . 33))

**(vector-sort**

*pred vector***)**

**(vector-sort**

*pred vector start***)**

**(vector-sort**

*pred vector start end***)**

Procedure

`vector-sort`

returns a new vector containing the elements of *vector*in sorted order using*pred*as the "less than" predicate. If*start*and*end*are given, they indicate the sub-vector that should be sorted.(vector-sort < (vector 7 4 9 1 2 8 5))

⇒ #(1 2 4 5 7 8 9)

**(vector-for-each**

*f vector1 vector2 ...***)**

`vector-for-each`

implements a simple vector iterator: it applies *f*to the corresponding list of parallel elements from

*vector1 vector2 ...*in the range

*[0, length)*, where

*length*is the length of the smallest vector argument passed. In contrast with

`vector-map`

, *f*is reliably applied to each subsequent element, starting at index 0, in the vectors.

(vector-for-each (lambda (x) (display x) (newline))

#("foo" "bar" "baz" "quux" "zot"))

⇒

foo

bar

baz

quux

zot

**(vector-for-each/index**

*f vector1 vector2 ...***)**

`vector-for-each/index`

implements a simple vector iterator: it applies *f*to the index

*i*and the corresponding list of parallel elements from

*vector1 vector2 ...*in the range

*[0, length)*, where

*length*is the length of the smallest vector argument passed. The only difference to

`vector-for-each`

is that `vector-for-each/index`

always passes the current index as the first argument of *f*in addition to the elements from the vectors

*vector1 vector2 ...*.

(vector-for-each/index

(lambda (i x) (display i)(display ": ")(display x)(newline))

#("foo" "bar" "baz" "quux" "zot"))

⇒

0: foo

1: bar

2: baz

3: quux

4: zot

**(vector-length**

*vector***)**

Returns the number of elements in

*vector*as an exact integer.**(vector-ref**

*vector k***)**

The

`vector-ref`

procedure returns the contents of element *k*of*vector*. It is an error if*k*is not a valid index of*vector*.(vector-ref ’#(1 1 2 3 5 8 13 21) 5) ⇒ 8

(vector-ref ’#(1 1 2 3 5 8 13 21) (exact (round (* 2 (acos -1))))) ⇒ 13

**(vector-set!**

*vector k obj***)**

The

`vector-set!`

procedure stores *obj*in element*k*of*vector*. It is an error if*k*is not a valid index of*vector*.(let ((vec (vector 0 '(2 2 2 2) "Anna")))

(vector-set! vec 1 '("Sue" "Sue"))

vec)

⇒ #(0 ("Sue" "Sue") "Anna")

(vector-set! '#(0 1 2) 1 "doe")

⇒ error ;; constant/immutable vector

**(vector-swap!**

*vector j k***)**

The

`vector-swap!`

procedure swaps the element *j*of*vector*with the element*k*of*vector*.Procedures which operate only on a part of a vector specify the applicable range in terms of an index interval [

*start*;*end*[; i.e. the*end*index is always exclusive.**(vector-copy!**

*to at from***)**

**(vector-copy!**

*to at from start***)**

**(vector-copy!**

*to at from start end***)**

Copies the elements of vector

*from*between*start*and*end*to vector*to*, starting at*at*. The order in which elements are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary vector and then into the destination.*start*defaults to 0 and*end*defaults to the length of*vector*.It is an error if

*at*is less than zero or greater than the length of*to*. It is also an error if`(- (vector-length to) at)`

is less than `(- end start)`

.(define a (vector 1 2 3 4 5))

(define b (vector 10 20 30 40 50)) (vector-copy! b 1 a 0 2)

b ⇒ #(10 1 2 40 50)

**(vector-fill!**

*vector fill***)**

**(vector-fill!**

*vector fill start***)**

**(vector-fill!**

*vector fill start end***)**

The

`vector-fill!`

procedure stores *fill*in the elements of*vector*between*start*and*end*.*start*defaults to 0 and*end*defaults to the length of*vector*.(define a (vector 1 2 3 4 5))

(vector-fill! a ’smash 2 4)

a ⇒ #(1 2 smash smash 5)

**(vector-reverse!**

*vector***)**

**(vector-reverse!**

*vector start***)**

**(vector-reverse!**

*vector start end***)**

Procedure

`vector-reverse!`

destructively reverses the contents of *vector*between*start*and*end*.*start*defaults to 0 and*end*defaults to the length of*vector*.(define a (vector 1 2 3 4 5))

(vector-reverse! a)

a ⇒ #(5 4 3 2 1)

**(vector-sort!**

*pred vector***)**

**(vector-sort!**

*pred vector start***)**

**(vector-sort!**

*pred vector start end***)**

Procedure

`vector-sort!`

destructively sorts the elements of *vector*using the "less than" predicate*pred*between the indices*start*and*end*. Default for*start*is 0, for*end*it is the length of the vector.(define a (vector 7 4 9 1 2 8 5))

(vector-sort! < a)

a ⇒ #(1 2 4 5 7 8 9)

**(vector-map!**

*f vector1 vector2 ...***)**

Similar to

`vector-map`

which maps the various elements into a new vector via function *f*, procedure`vector-map!`

destructively inserts the mapped elements into *vector1*. The dynamic order in which*f*gets applied to the elements is unspecified.(define a (vector 1 2 3 4))

(vector-map! + a #(10 20 30))

a ⇒ #(11 22 33 4)

**(vector-map/index!**

*f vector1 vector2 ...***)**

Similar to

`vector-map/index`

which maps the various elements together with their index into a new vector via function *f*, procedure`vector-map/index!`

destructively inserts the mapped elements into *vector1*. The dynamic order in which*f*gets applied to the elements is unspecified.(define a (vector 1 2 3 4))

(vector-map/index! (lambda (i x y) (cons i (+ x y))) a #(10 20 30))

a ⇒ #((0 . 11) (1 . 22) (2 . 33) 4)

**(vector->list**

*vector***)**

**(vector->list**

*vector start***)**

**(vector->list**

*vector start end***)**

The

`vector->list`

procedure returns a newly allocated list of the objects contained in the elements of *vector*between*start*and*end*in the same order line in*vector*.(vector->list ’#(dah dah didah)) ⇒ (dah dah didah)

(vector->list ’#(dah dah didah) 1 2) ⇒ (dah)

**(vector->string**

*vector***)**

**(vector->string**

*vector start***)**

**(vector->string**

*vector start end***)**

The

`vector->string`

procedure returns a newly allocated string of the objects contained in the elements of *vector*between*start*and*end*. This procedure preserves the order of the characters. It is an error if any element of vector between*start*and*end*is not a character.(vector->string #(#\1 #\2 #\3) ⇒ "123"

Last modified 5mo ago