9. Objectes i arrays

9.3. Arrays

Quan als nostres sketches tenim pocs elements, en podem tenir prou amb l’ús de variables, però quan comencem a tenir molts elements dels quals hem d’emmagatzemar alguna informació que varia al llarg de l’execució del programa, l’ús de variables ens pot quedar curt i necessitem noves estructures que ens permetin emmagatzemar i modificar dades de manera més senzilla i flexible. Amb l’últim exemple dels objectes vèiem que si volíem afegir una segona flor, només havíem d’afegir una variable nova, però, i si volem crear cinquanta flors? Crear una variable per a cadascuna no sembla que sigui molt eficient.

Els arrays són una estructura de dades que ens permet emmagatzemar moltes variables amb un mateix nom, la qual cosa ens permetrà treballar de manera molt més senzilla i eficient.

Treballar amb arrays és similar a treballar amb variables: necessitem crear-los i assignar-los valors que després utilitzarem.

Creant i assignant valors als arrays

Per crear un array, ho podem fer de la manera següent:

let values = [100, 200, 300];

Igual que amb les variables, utilitzem la paraula clau let seguida del nom que vulguem donar a l’array i, a continuació, li assignem els valors que vulguem entre claudàtors i separats amb una coma. Amb això, el que hem fet ha estat crear un array de tres elements. En aquest cas, li hem assignat valors numèrics, però podria ser qualsevol tipus de valor, fins i tot valors de diferents tipus en un mateix array:

let values = [100, 200, 300];
let colors = ["pink", "lightblue", "lightgreen"];
let booleans = [true, false, false, true];
let mixedValues = [23, true, "yellow"];

Accedint als valors d’un array

Figura 120. Estructura d’un array
Font: adaptació de L. McCarthy; A. P. C. Reas; B. Fry (2015). Getting Started with P5.Js: Making Interactive Graphics in JavaScript and Processing. Make Community, LLC.

Cadascun dels elements d’un array té un índex per determinar la seva posició a l’array. Igual que passa amb les coordenades, per a les posicions d’un array comencem a comptar des del zero.

Per accedir als elements de l’array necessitarem conèixer-ne l’índex. Prenent com a exemple l’array de la figura 120, podem accedir als seus elements de la manera següent:

console.log(years[0]);   // Imprimeix 1920
let x = years[2];
let y = years[4];
console.log(x + y);      // Imprimeix 3990 (1980 + 2010)

Una propietat dels arrays que ens resultarà molt útil serà la mida, que podem esbrinar mitjançant la seva propietat length:

let colors = ["pink", "blue", "red"];
console.log(colors.length);                // Imprimeix 3

let values = [];
console.log(values.length);                // Imprimeix 0

// Per accedir a l'últim element de qualsevol array
// sigui de la mida que sigui
console.log(colors[colors.length - 1]);    // Imprimeix "red"

De la mateixa manera que passa amb les variables, és comú que vulguem accedir a un array tant des del setup() com des del draw(), per la qual cosa ho voldrem declarar al principi del codi i més tard assignar-los valors. Això ho podem fer creant al principi del codi un array buit:

let values = [];

function setup() {
  values[0] = 34553;
  values[1] = 13234;
}

Vegem un petit exemple d’un array en ús per triar aleatòriament entre un set de colors preestablerts.

Figura 121. Usant arrays
Font: elaboració pròpia.

En aquest exemple, creem un array amb tres colors i a la funció chooseColor() triem aleatòriament mitjançant random() un nombre entre 0 i la mida de l’array (en aquest cas, entre 0 i 2) per després accedir a l’element de l’array l’índex del qual és aquest nombre aleatori i l’apliquem com a farciment del cercle. Si cliquem amb el ratolí, triarem un altre element de l’array a l’atzar. Triar un element aleatori dins d’un array és una operació bastant comuna en el món de la computació creativa i P5 ens ofereix una manera més senzilla de fer-ho usant random():

let colors = ["red", "green", "blue"];
let randomColor = random(colors);

Si a random() li passem com a paràmetre un array, ens retornarà directament un element a l’atzar d’aquest array.

Assignar i accedir als valors d’un array mitjançant bucles

Fins ara hem assignat i accedit als valors dels nostres arrays de manera «manual», amb la qual cosa realment no hem guanyat molt respecte a quan havíem de crear múltiples variables. No obstant això, podem automatitzar aquest procés utilitzant bucles tant per assignar valors als arrays com per accedir-hi.

Figura 122. Declarant i accedint a valors d’un array mitjançant bucles
Font: elaboració pròpia.

A l’exemple anterior creem un array buit al qual en el setup() li assignem 100 valors aleatoris usant el valor de i, que itera des de 0 fins a 99 per assignar el valor a l’índex corresponent de l’array. A continuació, en el draw() iterem a través de l’array prèviament creat usant també un bucle que va des de l’element 0 fins a l’element 99, ja que l’array té 100 elements i estem usant < y no <=. Usem aquests valors aleatoris emmagatzemats a l’array per dibuixar línies horitzontals en coordenades verticals aleatòries.

Tot això ho podríem replicar fent ús únicament de bucles i random(), però hauríem d’utilitzar també un noLoop() o manipular el frameRate() perquè els valors de les posicions a la coordenada y de les línies no canviés a cada frame, la qual cosa ens impediria utilitzar les capacitats interactives de P5. A més, tenim accés a aquests valors de posició en y, per la qual cosa podríem fer que aquests valors variessin al llarg del temps.

Dins d’un array podem emmagatzemar qualsevol tipus de dada, fins i tot altres arrays, la qual cosa pot resultar molt útil a l’hora de crear conjunts de coordenades (x, y) per exemple.

let positions = [[100, 50], [20, 70], [120, 60]];

console.log(positions[0]);     // Imprimeix [100, 50]
console.log(positions[0][0]);  // Imprimeix 100
console.log(positions[0][1]);  // Imprimeix 50

console.log(positions[1][0]);  // Imprimeix 20

Vegem un exemple una mica més complex utilitzant arrays dins d’un altre array:

Figura 123. Imbricant arrays
Font: elaboració pròpia.

En aquesta ocasió, a l’hora d’emplenar l’array ho hem fet amb altres arrays de dos elements, per la qual cosa a snowPos tenim un total de 120 elements i cadascun d’aquests emmagatzema al seu torn dos elements: valors aleatoris entre 0 i l’amplària o l’alçària del canvas. Aquests dos elements són als quals podem accedir mitjançant snowPos[i][0] i snowPos[i][1] per utilitzar-los com a coordenades dels nostres flocs de neu. Per donar-los moviment de caiguda, a cada element snowPos[i][1] (la coordenada y de cada floc) li anem augmentant el seu valor. Si veiem que surt de la pantalla, fem que torni a aparèixer per dalt i li donem un nou valor de snowPos[i][0] (la coordenada x).