Y e X - Sto sbagliando?


8

A volte mi imbatto in piccoli problemi durante i miei progetti JavaScript. Questo perché la maggior parte delle funzioni integrate di JavaScript esegue X, Y se sono necessarie posizioni. (In questo ordine).

Ma quando creo un array 2D, comincio con Y, mi sembra più logico eseguire l'asse X in orizzontale. Se non riesco a spiegarlo, lascia che ti mostri:

inserisci qui la descrizione dell'immagine

Quindi i miei loop sembrano così:

for(var y = 0; y < 10; y++){
    for(var x = 0; x < 10; x++){
        console.log("Doh!");
    }
}

È così folle? Vorrei convertirmi alla pratica normale in modo da avere un tempo più facile mentre costruisco il mio gioco e non devo fare cambi costanti.

Allora perché è X prima di Y?

Modifica: ecco un altro esempio, e probabilmente il motivo principale della mia confusione: X è orizzontale e Y è verticale nei miei libri.

[
[0,1,2,3,4],
[0,1,2,3,4],
[0,1,2,3,4],
[0,1,2,3,4],
]

3
Il mio primo istinto sarebbe perché etichettiamo punti come (X, Y) su un piano cartesiano.
Vaughan Hilts,

Immagino di sì, ma guarda il mio nuovo esempio di array. Mi sembra più giusto in quel modo
Oliver Schöning,

Risposte:


8

No, se funziona per te, non stai sbagliando. Se vuoi cambiare, allora fallo. L'ordine di elaborazione di righe / colonne è talvolta arbitrario, a volte no. L'ordine che usi dipende interamente dall'algoritmo che stai utilizzando.

Esistono diverse combinazioni diverse per l'elaborazione di X, Y. Sta a te scegliere quale è corretto per il tuo algoritmo. Nel caso in cui ciascuna iterazione sia indipendente da qualsiasi altra, puoi scegliere quale vuoi. Puoi cambiare quale è nel loop interno e puoi anche cambiare se i loop vanno da min a max o da max a min.

Immagino che l'impostazione predefinita sia:

for xmin to xmax
    for ymin to ymax

perché questo è spesso il modo in cui i dati sono disposti in memoria. (Non necessariamente vero per tutte le lingue poiché l'ordine dell'indice può cambiare).

Ad esempio, un array A[3][3]( A[X][Y]):

inserisci qui la descrizione dell'immagine

Dove il yvalore si trova prima negli incrementi del loop interno, quindi "passa sopra" per aumentare il xvalore. A parte questo, (X, Y) è il modo standard di scriverlo in matematica.


Saluti, beh, sembra "giusto" quando sto costruendo una griglia:
Oliver Schöning

4

Stai sbagliando ... in un certo senso. La cosa sbagliata che stai facendo è correlare l'ordine in cui le coordinate vengono scritte con l'ordine in cui i loop sono nidificati. Sono idee totalmente diverse!

Più specificamente, la cosa sbagliata è che il sistema di coordinate è legato in modo forte (e fragile) all'implementazione della memoria dei dati. Ciò significa che stai progettando un codice errato dal punto di vista OO. L'archiviazione dei dati dovrebbe essere opaca per ciò che lo utilizza e ciò che lo utilizza non dovrebbe interessare il modo in cui i dati vengono archiviati. L'utente dei dati deve solo sapere come ottenere l'informazione che desidera.

Quello che dovresti fare è trovare un modo per sottrarre la struttura dei dati dell'array nidificato e nasconderlo in un metodo simile getPoint(x,y). Quindi non devi preoccuparti di quale array è nidificato in quale ordine. Potresti lasciare la struttura dei tuoi dati all'indietro esattamente com'è, purché il tuo metodo getter sappia prima trovare l'array y e quindi cercare al suo interno l'elemento x. Ma qualunque codice stia chiamando getPoint()non lo sa. Deve solo conoscere le due coordinate a cui è interessato.


In altre parole: "Ai programmi non importa quanto sia bello il tuo codice!"
Oliver Schöning il

Ma c'è qualcosa che non va nel mio modo di conservarlo oltre a essere capovolto?
Oliver Schöning il

No, non la penso così; le altre risposte sono corrette in quel modo. Il mio punto riguarda solo il modo in cui ti crea confusione, che ho dedotto dal fatto che mi hai chiesto. Se la tua implementazione rende il tuo codice difficile da capire, allora incapsula quella stranezza dietro una buona interfaccia e dimenticala.
Seth Battin,

1

Non importa! Inoltre scrivo sempre prima Y (sembra più naturale). Quando hai la tua matrice in array come righe, puoi persino fare un po 'di optmizzazione. Invece di questo:

for(var y=0; y<h; y++){
    for(var x=0; x<w; x++){
        m[y*w+x] = a;
    }
}

puoi usare questo:

for(var y=0; y<h; y++){
    var i = y*w;
    for(var x=0; x<w; x++, i++){
        m[i] = a;
    }
}

ed evitare molte moltiplicazioni! :)


Potresti dirmi cosa fa meglio il tuo secondo esempio? : o In JavaScript non ci sono matrici 2D "reali", devi creare una matrice di matrici. Pertanto non so se posso usare il secondo esempio.
Oliver Schöning,

Diciamo, w = h = 1000. Nel primo esempio, stai facendo 1000000 moltiplicazioni, mentre nel secondo esempio stai facendo solo 1000 moltiplicazioni. La moltiplicazione è super difficile, molte CPU non hanno nemmeno il comando di moltiplicazione. Lo stanno emulando con operazioni di addizione e bit.
Ivan Kuckir il

Vedo. Ma non mi vedo fare una simile iterazione. I miei di solito sembrano così: for (var y ...) {array [y] = [] for (var x ...) {array [y] [x] = a;}}
Oliver Schöning

1
Oh certo. Ma stai creando 1000 nuovi oggetti JS sull'heap ... oh, non importa, probabilmente non stai implementando Adobe Photoshop in JS, quindi continua a usare le tue iterazioni :)
Ivan Kuckir
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.