Y et X - Je me trompe?

8

Je rencontre parfois de petits problèmes lors de mes projets JavaScript. En effet, la plupart des fonctions intégrées de JavaScript exécutent X, Y si des positions sont nécessaires. (Dans cet ordre).

Mais lorsque je construis un tableau 2D, je commence par Y, il me semble plus logique de faire fonctionner l'axe X horizontalement. Si je suis mal à l'expliquer, laissez-moi vous montrer:

entrez la description de l'image ici

Donc mes boucles ressemblent à ceci:

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

Est-ce si fou? Je voudrais me convertir à la pratique normale afin d'avoir un temps plus facile lors de la construction de mon jeu et de ne pas avoir à faire des switcherroos constants.

Alors pourquoi est-ce X avant Y?

Edit: Voici un autre exemple, et probablement la principale raison de ma confusion: X est horizontal et Y est vertical dans mes livres.

[
[0,1,2,3,4],
[0,1,2,3,4],
[0,1,2,3,4],
[0,1,2,3,4],
]
Oliver Schöning
la source
3
Mon premier instinct serait parce que nous étiquetons des points comme (X, Y) sur un plan cartésien.
Vaughan Hilts
Je suppose que oui, mais regardez mon nouvel exemple de tableau. Cela me semble plus juste de cette façon
Oliver Schöning

Réponses:

8

Non, si cela fonctionne pour vous, vous ne vous trompez pas. Si vous souhaitez changer, faites-le. L'ordre dans lequel vous traitez les lignes / colonnes est parfois arbitraire, parfois non. L'ordre que vous utilisez dépend entièrement de l'algorithme que vous utilisez.

Il existe plusieurs combinaisons différentes pour le traitement de X, Y. C'est à vous de choisir celui qui convient à votre algorithme. Dans le cas où chaque itération est indépendante de toute autre, vous pouvez choisir celle que vous souhaitez. Vous pouvez changer ce qui est dans la boucle intérieure et vous pouvez également changer si les boucles vont de min à max ou max à min.

J'imagine que la valeur par défaut est:

for xmin to xmax
    for ymin to ymax

car c'est souvent ainsi que les données sont organisées en mémoire. (Pas nécessairement vrai pour toutes les langues car l'ordre de l'index peut changer).

Par exemple, un tableau A[3][3]( A[X][Y]):

entrez la description de l'image ici

Lorsque la yvaleur se trouve dans la boucle interne, elle s'incrémente en premier, puis "survole" pour augmenter la xvaleur. En dehors de cela, (X, Y) est la façon standard de l'écrire en mathématiques.

MichaelHouse
la source
À la vôtre, eh bien, ça "semble juste" quand je construis une grille:
Oliver Schöning
4

Vous vous trompez ... en quelque sorte. La mauvaise chose que vous faites est de corréler l'ordre dans lequel les coordonnées sont écrites avec l'ordre dans lequel les boucles sont imbriquées. Ce sont des idées totalement différentes!

Plus précisément, la mauvaise chose est que votre système de coordonnées est lié de manière forte (et fragile) à votre implémentation de votre stockage de données. Cela signifie que vous concevez un mauvais code du point de vue OO. Le stockage de données doit être opaque à la chose qui l'utilise et la chose qui l'utilise ne doit pas se soucier de la façon dont les données sont stockées. L'utilisateur des données a seulement besoin de savoir comment obtenir l'information qu'il souhaite.

Ce que vous devez faire est de trouver un moyen d'abstraire votre structure de données de tableau imbriqué et de la masquer dans une méthode comme getPoint(x,y). Ensuite, vous n'avez pas à vous soucier de quel tableau est imbriqué dans quel ordre. Vous pouvez laisser votre structure de données en arrière exactement telle qu'elle est, tant que votre méthode getter sait d'abord trouver le tableau y, puis rechercher en son sein l'élément x. Mais quel que soit le code appelant, getPoint()il ne le sait pas. Il lui suffit de connaître les deux coordonnées qui l'intéressent.

Seth Battin
la source
En d'autres termes: "Les programmes ne se soucient pas de la beauté de votre code!"
Oliver Schöning
Mais y a-t-il quelque chose qui cloche dans ma façon de le stocker en plus d'être à l'envers?
Oliver Schöning
Non je ne pense pas; les autres réponses sont correctes de cette façon. Ce que je veux dire, c'est seulement comment cela vous cause de la confusion, ce que j'ai déduit du fait que vous avez demandé. Si votre implémentation rend votre code difficile à comprendre, alors encapsulez cette bizarrerie derrière une bonne interface et oubliez-la.
Seth Battin
1

Ce n'est pas important! J'écris également toujours Y en premier (semble plus naturel). Lorsque vous avez votre matrice dans un tableau sous forme de lignes, vous pouvez même faire une optimisation. Au lieu de cela:

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

vous pouvez utiliser ceci:

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

et évitez les multiplications! :)

Ivan Kuckir
la source
Pourriez-vous me dire ce que votre deuxième exemple fait de mieux? : o En JavaScript, il n'y a pas de "vrais" tableaux 2D, vous devez créer un tableau de tableaux. Je ne sais donc pas si je peux utiliser le deuxième exemple.
Oliver Schöning
Disons que w = h = 1000. Dans le premier exemple, vous effectuez 1000000 multiplications, tandis que dans le deuxième exemple, vous ne faites que 1000 multiplications. La multiplication est super difficile, de nombreux processeurs n'ont même pas de commande de multiplication. Ils l'émulent avec des opérations d'addition et de bits.
Ivan Kuckir
Je vois. Mais je ne me vois pas faire une telle itération. Le mien ressemble généralement à ceci: for (var y ...) {array [y] = [] for (var x ...) {array [y] [x] = a;}}
Oliver Schöning
1
Oh, bien sûr. Mais vous créez 1000 nouveaux objets JS sur le tas ... oh tant
pis, vous n'implémentez