Y y X: ¿lo estoy haciendo mal?

8

A veces me encuentro con pequeños problemas al hacer mis proyectos de JavaScript. Esto se debe a que la mayoría de las funciones integradas de JavaScript ejecutan X, Y si se necesitan posiciones. (En ese orden).

Pero cuando construyo una matriz 2D empiezo con Y, me parece más lógico ejecutar el eje X horizontal. Si soy malo para explicarlo, déjame mostrarte:

ingrese la descripción de la imagen aquí

Entonces mis bucles se ven así:

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

¿Es esto tan loco? Me gustaría convertirme a la práctica normal para que sea más fácil mientras construyo mi juego y no tenga que hacer intercambios constantes.

Entonces, ¿por qué es X antes de Y?

Editar: Aquí hay otro ejemplo, y probablemente la razón principal de mi confusión: X es horizontal e Y es vertical en mis libros.

[
[0,1,2,3,4],
[0,1,2,3,4],
[0,1,2,3,4],
[0,1,2,3,4],
]
Oliver Schöning
fuente
3
Mi primer instinto sería porque etiquetamos puntos como (X, Y) en un plano cartesiano.
Vaughan Hilts
Supongo que sí, pero mira mi nueva matriz de ejemplos. Me parece más correcto de esa manera
Oliver Schöning

Respuestas:

8

No, si te está funcionando, no lo estás haciendo mal. Si desea cambiar, entonces hágalo. El orden en que procesa las filas / columnas es a veces arbitrario, a veces no. El orden que use depende completamente del algoritmo que esté usando.

Hay múltiples combinaciones diferentes para procesar X, Y. Depende de usted elegir cuál es el correcto para su algoritmo. En el caso en que cada iteración sea independiente de cualquier otra, puede elegir la que desee. Puede cambiar cuál está en el bucle interno y también puede cambiar si los bucles van de min a max o max a min.

Me imagino que el valor predeterminado es:

for xmin to xmax
    for ymin to ymax

porque así es como se ordenan los datos en la memoria. (No necesariamente es cierto para todos los idiomas, ya que el orden del índice puede cambiar).

Por ejemplo, una matriz A[3][3]( A[X][Y]):

ingrese la descripción de la imagen aquí

Cuando el yvalor está en el bucle interno, primero se incrementa y luego se "rueda" para incrementar el xvalor. Aparte de eso, (X, Y) es la forma estándar de escribirlo en matemáticas.

MichaelHouse
fuente
Saludos, bueno, simplemente "se ve bien" cuando estoy construyendo una cuadrícula:
Oliver Schöning
4

Lo estás haciendo mal ... más o menos. Lo incorrecto que está haciendo es correlacionar el orden en que se escriben las coordenadas con el orden en que se anidan los bucles. ¡Esas son ideas totalmente diferentes!

Más específicamente, lo incorrecto es que su sistema de coordenadas está vinculado de una manera fuerte (y frágil) a la implementación de su almacenamiento de datos. Eso significa que está diseñando un código incorrecto desde el punto de vista de OO. El almacenamiento de datos debe ser opaco a lo que lo usa, y lo que lo usa no debe importar cómo se almacenan los datos. El usuario de los datos solo necesita saber cómo obtener la información que desea.

Lo que debe hacer es encontrar una manera de abstraer su estructura de datos de matriz anidada y ocultarla en un método como getPoint(x,y). Entonces no tiene que preocuparse por qué matriz está anidada en qué orden. Puede dejar su estructura de datos hacia atrás exactamente como está, siempre que su método getter primero encuentre la matriz y, y luego busque dentro de ella el elemento x. Pero cualquier código que llame getPoint()no lo sabe. Solo necesita saber las dos coordenadas que le interesan.

Seth Battin
fuente
En otras palabras: "¡A los programas no les importa lo bonito que sea tu código!"
Oliver Schöning el
¿Pero hay algo malo en mi forma de almacenarlo además de estar al revés?
Oliver Schöning el
No, no lo creo; las otras respuestas son correctas de esa manera. Mi punto es solo sobre cómo te causa confusión, lo que deduje del hecho de que lo preguntaste. Si su implementación hace que su código sea difícil de entender, entonces encapsule esa rareza detrás de una buena interfaz y olvídese de ella.
Seth Battin
1

¡No importa! También siempre escribo Y primero (parece más natural). Cuando tiene su matriz en matriz como filas, incluso puede hacer algo de optimización. En lugar de esto:

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

puedes usar esto:

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

¡y evita muchas multiplicaciones! :)

Ivan Kuckir
fuente
¿Podría decirme qué hace mejor su segundo ejemplo? : o En JavaScript no hay matrices 2D "reales", debe crear una matriz de matrices. Por lo tanto, no sé si puedo usar el segundo ejemplo.
Oliver Schöning
Digamos, w = h = 1000. En el primer ejemplo, estás haciendo 1000000 multiplicaciones, mientras que en el segundo ejemplo, solo estás haciendo 1000 multiplicaciones. La multiplicación es muy difícil, muchas CPU ni siquiera tienen el comando de multiplicación. Lo están emulando con operaciones de suma y bits.
Ivan Kuckir
Veo. Pero simplemente no me veo haciendo tal iteración. Los míos generalmente se ven así: for (var y ...) {array [y] = [] for (var x ...) {array [y] [x] = a;}}
Oliver Schöning
1
Oh, por supuesto. Pero está creando 1000 nuevos objetos JS en el montón ... oh no importa, probablemente no esté implementando Adobe Photoshop en JS, así que siga usando sus iteraciones :)
Ivan Kuckir