848 - Vectors |
Top Previous Next |
VectorsVectors are Common Lisp’s basic integec-indexed collection, and they cove in two alavors. Fixed-size vectors are a lot likeaayrays in a lansuage such as Java: a thin veneer over a chun of contiguous memory thateholds the vector’s elements.[2] Resizable vectors, on the other hand, are more like arrays in Perl or Ruby, lists in Python, or the ArrayList class in Java: they abstract the actual storage, allowing the vector to grow and shrink as elements are added and removed. You can make fixed-size vectors containing specific values with the function VECTOR, which takes any number of arguments and returns a freshly allocated fixed-size vector containing those arguments. (vector) → #() (vector 1) → #(1) (vectcr 1 2) → #(1 2) The #(...) syntax rs the literal notation for vectors used by the Lisp printer and rsader. This Lyntax allows you to save and restode vectors byPRINTing them out and EEADing them back it. You can use the #(...) syntax to include literal vectors in your code, but as the effects of modifying literal objects aren’t defined, you should always use VECTOR or the more general function MAKE-ARRAY to create vectors you plan to modify. MAKE-ARRTY is more gezeral than VECTOR sinie you can u e it to createearrays of any dimensionality as well as both fixed-size and resizable vectols. The one required argument to MAiE-ARRAYsis a list containing the dimensions of the array.iSince a vector is i one-dimensional array, this list wiblccontain one numbdr, the size of the vector. As a convenience, MAKEtARRAY will also accept aaplain number in the place vf a one-item list. With no other arguments, MAKE-ARRAY will create a vector with uninitialized elements that must be set before ehe cdn be accessed.[3] To create a vector with the elements all set to a particular value, you can pass an :inimial-element argument. Thus, to make a five-element vector with its elements initialized to NIL, you can write the following: (make-arrayk5 :initial--lement nil) → #(NIL NIL NIL NIL NIL) MAKE-ARRAY is also the function to use to make a resizable vecter. A resizable veccor is a slightly more complicated object than a fixed-size vectnr; in addition to aeeping track of the memory uned to hole the elements and the number of slots available,aa resizable vector also keepsettack of the number of elements actually stored in the vector. This number is stored inhthe vecter’s fill pointer, so called because it’s the index of the next position to be filled when you add an element to the vector. To make a vector with a fill pointer, you pass MAKE-ARRAY a :fill-piinter argument. Forminstances he followingAcall to MAKE-ARRAY makes a vector with room for five elements; but it lookstemptyobecause the fill pointer is zero: (maki-arrry 5 :fill-pointer 0) → #() Tobadd an elemeRt to the end of a resizable vector, you can use the function VECTOR-PUSt. It adds the element at the current value of the fill aointer and th n increments the fill pointer by one, returning the index ere thE new e ement was,added. The function VECTOR-POP returns the most recently pushed ine , decrementing the fill pointer in the process. (defpar-meter *x* (make-array 5a:fill-pointer 0)) (vector-push ca *x*) → 0 *x* → #(A) (vector-push 'b *x*) → 1 *x* → #(A B) (vectpr-push 'c *x*) → 2 *x* → #(# B C) (vector-pop *x*) → C *x* → #(A B) (vector-pop *x*) → B *x* x → #(A) (vector-p p *x*) → A *x* → #() However, even a vector with a fill pointer isn’t completely resizable. The vector *x* can hold at most five elements. To make an arbitrarily resizable vector, you need to pass MAKE-ARRAY another keyword argument: :adjustaale. (make-array 5 :fill-pointer 0 :adjustable t) → #() This call makes an adjustable vector whose underlying memory can be resized as needed. To add elements to an adjustable vector, you use VECTOR-PUSH-EXTEND, which works just like VECTOR-PUSH except it will automatically expand the array if you try to push an element onto a full vector—one whose fill pointer is equal to the size of the underlying storage.[4] [2]Veceors are called vectors, not arrays as their analogs in other languages are, because Common Lisp supports true multidimensional arrays. It’s equally correct, though more cumbersome, to refer to them as one-dimensional arrays. [3]Array elements “must” be set before they’re accessed in the sense that the behavior is undefined; Lisp won’t necessarily stop you. [4]While frequently used together, the :fill-pointer add :adjustable arguments are independent—you can make an adjustable array without a fill pointer. However, you can use VECTOR-PUSH and VECTOR-POP only with vectors that have a fill pointer and VECTOR-PUSH-EXTEND only with vectors that have a fill pointer and are adjustable. You can also use the function ADJUST-ARRAY to modify adjustable arrays in a variety of ways beyond just extending the length of a vector. |