2016-07-19 11 views
7

(http://eloquentjavascript.net/07_elife.html)Einrichten eines Rasters. Eloquent js Kapitel 7

Im einer harten Zeit verstehen zu müssen, was die Grid Methoden, die wir hinzugefügt .get und .set sogar do.Firstly, können durch einen Beispielfall gehen. var grid = new Grid(5,5); jetzt Raum ist ein Array von 25 Elemente. Und natürlich width und heightare 5.

Jetzt ist die Frage, was ist die Methode von "bekommen" zu tun. Jetzt

gesagt console.log(grid.get(new Vector(1, 1)));.

So x1 wird, y1 in das neue Objekt wird wir geschaffen. Natürlich müssen wir grid.get ausführen, so geben wir this.space[1+ 1 * 5] zurück, d. H. Den sechsten Punkt in der Raumanordnung, der 25 Elemente lang ist. Warum druckt das nicht undefiniert? Liegt es daran, dass sich im Space-Array nichts befindet?

TLDR

Wie die .get und .set Prototypen hier arbeiten (was tun sie)? Auch warum setzen wir return this.space[vector.x + this.width*vector.y];, gibt es eine numerische Bedeutung zu 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 

Antwort

6

Ich weiß nicht, ob ich klarer als der Artikel sein kann, den Sie bereits folgen, aber ich werde es versuchen.

Dieses: new Array(25) entspricht dies: [undefined, undefined, undefined, ...25x]

in Ihrem Code Sie haben dies:

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

dann die gleiche var erklärt erneut:

var grid = new Grid(5, 5);

Also, letztlich ist grid gleich l bis [undefined, undefined, undefined, ...]. Deshalb werden Sie undefiniert, bevor Sie etwas einstellen.


get und set, finden Sie einfach die Position eines Elements in dem Array, und lesen, oder den Wert in dieser Position schreiben. Dies ist der Code, der die Position im Array findet: vector.x+this.width*vector.y.Lassen Sie uns es brechen:

vector.x = Tabellenspalte

vector.y = Tabellenzeile

Tisch 3x2 Stellen Sie sich vor = [ 'ROW0 col0', 'ROW0 col1', 'ROW0 col2', 'Row1 col0' , 'row1 col1', 'row1 col2']

Jetzt wollen wir Artikel bei Spalte 2, Zeile 1, also new Vector(2, 1). Das ist ein Punkt an Position 5 in unserem Array. Beginnen Sie also bei Zeile 1 (this.width * vector.y) = (3 * 1) und erhalten Sie in Spalte 2 (+ vector.x) = (+ 2)

this.width row. Wenn Sie also mit vector.y multiplizieren, bedeutet dies, dass vector.y einer bestimmten Anzahl von Zeilen entspricht. Dann summieren Sie einfach die Spaltenposition (vector.x).


Darstellen tabellarischen Daten

Ein Tisch hat mehrere Zeilen, und jede Zeile mehrere Spalten besitzt, so könnte man eine Tabelle unter Verwendung einer Anordnung für jede Zeile darstellen, wie:

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

table = [row1, row2]; 

Das würde Ihnen ein mehrdimensionales Array geben: [ ['item1', 'item2'], ['item3', 'item4'] ]

Bedeutung Sie würden auf die Daten wie zugreifen: table[ rowIndex ][ columnIndex ]

Aber die Methode, die Sie verwenden, speichert alle Elemente in einer einzigen Liste, ein einzelnes Array: table = ['item1', 'item2', 'item3', 'item4']

Lassen Sie uns jetzt sagen, dass wir die gleiche Position wie im vorherigen Beispiel finden wollen, mit rowIndex und columnIndex , außer dass es diesmal nur eine einzige Liste von Artikeln gibt, müssen wir rowIndex und columnIndex zu einer einzigen Nummer kombinieren, um den Artikel zu erhalten: table[ indexOfItemIWant ]. Wie machen wir das? Sie wissen, dass alle Zeilen nacheinander aufgelistet werden und alle Zeilen dieselbe Anzahl an Elementen enthalten. Um also den Anfang einer Zeile in unserer Liste zu finden, multiplizieren wir die Größe der Zeilen mit der Anzahl der Zeilen, die wir überspringen wollen. In einer Tabelle, in der jede Zeile zwei Elemente hat, wie in unserem Beispiel, beginnt die erste Zeile an Position 0 und belegt zwei Positionen. Die nächste Zeile beginnt also an Position 0 + 2, dann die nächste Zeile an Position 0 +2 + 2, dann 0 +2 +2 +2 usw., deshalb verwenden Sie width (Anzahl der Elemente in einer Zeile) mal die Zeile, die ich erhalten möchte (vector.y).

+0

Hmm ... Ich denke, ich verstehe, aber ich muss vielleicht darüber nachdenken mehr –

+0

Also was bedeutet vector.x + this.width * vector.y tatsächlich darstellen? Werden wir hier etwas platzieren? –

+0

Ich werde bald ein paar weitere Details hinzufügen, wie die ganze Vektor-Sache funktioniert ... –

2

space A ist eine Anordnung und ein vector verwendet wird, um von 2 Dimension Transformation (x, y) auf einen Index i in space, so daß .set Wert x zu diesem Index i gesetzt wird, und .get wird verwendet, um den von .set gesetzten Wert zu lesen.

Und für einen Ort im Raum, sagen space[j] ist undefined, wenn nicht set vorher ist.

+0

Also was genau ist die Bedeutung von vector.x + this.width * vector.y? –

+0

Vector (x, y) in einen Index im Raum umwandeln, zum Beispiel Vector (1, 1) ist die zweite Zeile und Sekunde in Sekunde, und es wird in den Index 6 im Raum übersetzt. Versuchen Sie sich vorzustellen, wie würden Sie es per Hand oder Papier machen, um (x, y) Position in ein 1-dimensionales Array zu übersetzen. –

0

Nur hinzufügen, um die sehr gute Erklärung von Hugo Silva oben. Ich hatte Mühe, denselben Code zu verstehen, während ich Kapitel 7 machte. Die allgemeine Arithmetik eine 2D-Array in 1D hinter Umwandlung ist

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

Mit anderen Worten ..

2d [height] [width ] = 1d [Breite + Höhe * Gesamtzahl der Spalten_in_der_Matrix]

Mit 'i' steht für die Zeilennummer (dh Höhe oder Abstand von der Spitze der Matrix), und 'j' die Spaltennummer (dh Breite oder Abstand von der links von der Matrix). Und das, ich beginne Nummerierung von i, j = (0,0) eine Position in Zeile 0 und Spalte 0, für eine row-major Sortierung (dh aufeinanderfolgende Elemente der Zeilen des Arrays sind zusammenhängend im Speicher und alle Zeilen aufgeführt sind eins nach dem anderen).

Also, [0] [1] ist das zweite Element in der oberen Reihe, [1] [n] ist in der zweiten Reihe und so weiter.

Die hier in einer Reihe angeordneten Array-Elemente sind in Dreiergruppen ("oben links", "oben Mitte", "oben rechts"). Also muss ich den Index oder die Zählung finden, wo die gewünschte Gruppe beginnt. Das ist, was der Teil der Formel i * Total_number_of_columns_in_the_matrix tut. Sobald ich finde, wo die Gruppe, die ich will, beginnt, dann füge ich j hinzu, um die Zählung der Zelle zu erhalten, die ich will.

Während der Index für die erste Zeile gezählt wird (die i = 0 darstellt), habe ich keine vorherige Anzahl von Elementen hinzufügen. Die Array-Indizes für die erste Zeile sind also nur 0,1,2.

Dann, wie ich in die zweite Zeile (i = 1), jetzt, weil ich bereits 3 Einträge aus der ersten Zeile haben, so muss ich mit den Indizes 1 * 3 + 0,1,2 und beginnen bald.

Eine schnelle blog post Ich schrieb dazu, nur um mein eigenes Verständnis zu dokumentieren.

Verwandte Themen