2016-07-19 304 views
7

(http://eloquentjavascript.net/07_elife.html)Impostazione di una griglia. Eloquente js capitolo 7

Im avendo difficoltà a capire quali sono i metodi di griglia abbiamo aggiunto .get e .SET anche do.Firstly, lascia andare attraverso un caso di esempio. var grid = new Grid(5,5); ora lo spazio è un array di elementi 25. E naturalmente width e heightare 5.

Ora la domanda è qual è il metodo per "fare".

Ora abbiamo detto console.log(grid.get(new Vector(1, 1)));.

Così x diventa 1, y diventa 1 nel nuovo oggetto che abbiamo creato. Ovviamente abbiamo bisogno di fare grid.get quindi restituiamo this.space[1+ 1 * 5] il sesto posto nello spazio array che è lungo 25 elementi. Quindi perché questa stampa è indefinita? È perché non c'è nulla nell'array spaziale?

TLDR

Come le .get e .set prototipi lavoro qui (cosa fanno)? Inoltre, perché impostiamo return this.space[vector.x + this.width*vector.y];, c'è qualche significato numerico a vector.x+this.width*vector.y?

function Vector(x,y){ 
     this.x = x; 
     this.y = y; 
    } 

    Vector.prototype.plus = function(other){ 

     return new Vector(this.x + other.x, this.y + other.y); 
    } 


    var grid = ["top left", "top middle", "top right", 
     "bottom left", "bottom middle", "bottom right"]; 


    function Grid (width,height){ 

     this.space = new Array(width * height); 
     this.width = width; 
     this.height = height; 

    } 

    Grid.prototype.isInside = function(vector){ 


     return vector.x >=0 && vector.x<this.width && vector.y>=0 && vector.y<this.height; 

    } 

    Grid.prototype.get = function(vector){ 

     return this.space[vector.x + this.width*vector.y]; 
     // 5 + 5 * 1; 

    } 

    Grid.prototype.set = function(vector,value){ 

     this.space[vector.x + this.width *vector.y] = value; 

    } 

    var grid = new Grid(5, 5); 

    console.log(grid.get(new Vector(1, 1))); 
    // → undefined 
    grid.set(new Vector(1, 1), "X"); 
    console.log(grid.get(new Vector(1, 1))); 
    // → X 

risposta

6

Non so se posso essere più chiaro dell'articolo che stai già seguendo, ma farò un tentativo.

questo: new Array(25) è equivalente a questo: [undefined, undefined, undefined, ...25x]

Nel codice, si dispone di questo:

var grid = ["top left", "top middle", "top right", "bottom left", "bottom middle", "bottom right"];

poi dichiarare di nuovo la stessa var:

var grid = new Grid(5, 5);

Quindi, in definitiva, grid equa da [undefined, undefined, undefined, ...]. Ecco perché non sei definito prima di impostare qualcosa.


get e set, semplicemente trovare la posizione di un elemento dell'array, e leggere o scrivere il valore nella detta posizione. Questo è il codice che trova la posizione nell'array: vector.x+this.width*vector.y.Rompiamo giù:

vector.x = tavolo colonna

vector.y = tavolo fila

Immaginate un tavolo 3x2 = [ 'row0 col0', 'row0 col1', 'row0 col2', 'row1 col0' , 'row1 col1', 'row1 col2']

ora vogliamo articolo a colonna 2, riga 1, quindi new Vector(2, 1). Questo è l'oggetto nella posizione 5 del nostro array. Quindi, a partire dalla riga 1 (this.width * vector.y) = (3 * 1), ottieni l'articolo alla colonna 2 (+ vector.x) = (+ 2)

this.width è la dimensione di ogni fila, quindi quando si moltiplica per vector.y, significa che vector.y è equivalente a un certo numero di righe. Quindi da lì, somma la posizione della colonna (vector.x).


rappresentare dati tabulari

Una tabella ha diverse righe e ogni riga ha diverse colonne, quindi si può rappresentare una tabella utilizzando un array per ogni riga, come:

row1 = ['item1', 'item2']; 
row2 = ['item3', 'item4']; 

table = [row1, row2]; 

Questo ti darebbe un array multidimensionale: [ ['item1', 'item2'], ['item3', 'item4'] ]

Significa che accederai ai dati come: table[ rowIndex ][ columnIndex ]

Ma il metodo che si sta utilizzando, memorizza tutti gli elementi di una sola lista, un singolo array: table = ['item1', 'item2', 'item3', 'item4']

Ora diciamo che vogliamo trovare lo stesso elemento come nell'esempio precedente, utilizzando rowIndex e columnIndex , eccetto che questa volta c'è solo una lista di articoli, quindi dobbiamo combinare rowIndex e columnIndex in un unico numero, per ottenere l'oggetto usando: table[ indexOfItemIWant ]. Come lo facciamo? Sai che tutte le righe sono elencate una dopo l'altra e tutte le righe hanno lo stesso numero di elementi. Quindi per trovare l'inizio di una riga nella nostra lista, moltiplichiamo la dimensione delle righe, in base alla quantità di righe che vogliamo saltare. In una tabella in cui ogni riga ha due elementi, come nel nostro esempio, la prima riga inizia alla posizione 0 e occupa due posizioni, quindi la riga successiva, inizia dalla posizione 0 + 2, quindi dalla successiva, nella posizione 0 +2 + 2, quindi 0 +2 +2 +2 e così via, ecco perché si usa width (numero di elementi in una riga) volte la riga che voglio ottenere (vector.y).

+0

Hmm ... Penso di aver capito ma potrei aver bisogno di pensarci più –

+0

Quindi cosa rappresenta in realtà vector.x + this.width * vector.y? È quello dove metteremo qualcosa? –

+0

Aggiungerò presto qualche altro dettaglio su come funziona l'intera cosa vettoriale ... –

2

Un space è una matrice e un vector viene utilizzato per trasformare da 2 dimensione (x, y) ad un indice i in space, cosicché .set imposterà un valore x a tale indice i, e .get è usato per ottenere/leggere qualsiasi valore impostato da .set.

E per una posizione all'interno dello spazio, ad esempio space[j] non è definito se non è stato set precedente.

+0

Quindi qual è esattamente il significato di vector.x + this.width * vector.y? –

+0

Trasforma il vettore (x, y) in un indice nello spazio, ad esempio Vector (1, 1) è la seconda riga e il secondo in secondo, e tradotto in indice 6 nello spazio. Cercando di immaginare come lo faresti a mano o su carta per tradurre (x, y) la posizione in una matrice a 1 dimensione. –

0

Basta aggiungere alla spiegazione molto buona di Hugo Silva sopra. Stavo cercando di capire lo stesso codice, mentre facevo il capitolo 7. L'aritmetica generale dietro convertire una matrice 2D in 1D è

2d [i] [j] = 1d [j + i * Total_number_of_columns_in_the_matrix]

In altre parole ..

2d [altezza] [larghezza ] = 1d [larghezza + altezza * Numero totale_di_colonne_in_la matrice]

Con "i" che rappresenta il numero di riga (cioè altezza o distanza dalla parte superiore della matrice) e "j" il numero della colonna (cioè larghezza o distanza dal a sinistra di Matrix). E quello, inizio numerando da i, j = (0,0) che rappresenta una posizione alla riga 0 e colonna 0, per un ordinamento row-major (cioè gli elementi consecutivi delle righe dell'array sono contigui in memoria e tutte le righe sono elencate uno dopo l'altro).

Quindi, [0] [1] è il secondo elemento della riga superiore, [1] [n] è nella seconda riga e così via.

Gli elementi dell'array qui in una singola fila sono in gruppi di 3 ("alto a sinistra", "medio alto", "destra"). Quindi, ho bisogno di trovare l'indice o il conteggio di dove sta iniziando il gruppo che voglio. Questo è ciò che fa la parte della formula i * Numero_totale_di_colonne nella matrice. Una volta trovato dove inizia il gruppo che voglio, allora aggiungo j per ottenere il conteggio della cella che voglio.

Sebbene contare l'indice per la prima fila (che rappresenta i = 0), non ho alcuna conteggi precedenti di elementi da aggiungere. Quindi gli indici di array per la prima riga saranno solo 0,1,2.

Quindi, mentre arrivo alla seconda riga (i = 1), ora, perché, ho già 3 voci dalla prima riga, quindi devo iniziare con gli indici 1 * 3 + 0,1,2 e presto.

Un rapido blog post ho scritto su questo, solo per documentare la mia comprensione.