YおよびX-私はそれを間違っていますか?


8

JavaScriptプロジェクトを実行しているときに、小さな問題が発生することがあります。これは、JavaScriptのほとんどの組み込み関数が、位置が必要な場合にX、Yを実行するためです。(この順序で)。

しかし、2D配列を作成するときは、Yから始めて、X軸を水平に実行する方が理にかなっています。説明が苦手な場合は、以下に説明します。

ここに画像の説明を入力してください

だから私のループは次のようになります:

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

これは非常識ですか?ゲームを構築する時間をより簡単にし、常にスイッチャー操作を行う必要がないように、通常の方法に切り替えたいと思います。

では、なぜYの前にXがあるのでしょうか。

編集:これは別の例であり、おそらく私の混乱の主な理由です。私の本ではXは水平で、Yは垂直です。

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

3
私の最初の本能は、デカルト平面上の(X、Y)のようなポイントにラベルを付けるためです。
Vaughan Hilts 2013年

私はそう思いますが、私の新しい例の配列を見てください。そのように私にはより適切に見えます
OliverSchöning

回答:


8

いいえ、それがあなたのために働いていれば、あなたはそれを間違っているのではありません。切り替える場合は、切り替えてください。行/列を処理する順序は、任意である場合とそうでない場合があります。使用する順序は、使用しているアルゴリズムに完全に依存します。

X、Yの処理には複数の異なる組み合わせがあります。アルゴリズムに適したものを選択するのはあなた次第です。各反復が他の反復から独立している場合は、どちらを使用するかを選択できます。どちらが内側のループにあるかを切り替えることができ、ループが最小から最大、または最大から最小に移行するかどうかを切り替えることもできます。

デフォルトは次のようになると思います:

for xmin to xmax
    for ymin to ymax

これは、多くの場合、データがメモリに配置される方法だからです。(インデックスの順序が変わる可能性があるため、必ずしもすべての言語に当てはまるわけではありません)。

たとえば、配列A[3][3]A[X][Y]):

ここに画像の説明を入力してください

ここで、y値が「ロールオーバー」内部ループ最初、次に単位である増分するx値。それ以外では、(X、Y)は数学でそれを書くための標準的な方法です。


乾杯、私がグリッドを構築しているとき、それはちょうど「正しく見える」:
OliverSchöningMar

4

あなたはそれを間違っています...ちょっと。間違っているのは、座標が書き込まれる順序とループがネストされる順序を関連付けることです。それらはまったく異なるアイデアです!

より具体的に言うと、間違っているのは、座標系がデータストレージの実装に強力な(そして脆弱な)方法で結び付けられていることです。つまり、オブジェクト指向の観点から悪いコードを設計しているということです。データストレージは、それを使用するものに対して不透明である必要があり、それを使用するものは、データがどのように格納されるかを気にする必要はありません。データのユーザーは、必要な情報を取得する方法を知っている必要があるだけです。

あなたがすべきことは、ネストされた配列データ構造を抽象化し、それをのようなメソッドで隠す方法を見つけることgetPoint(x,y)です。そうすれば、どの配列がどの順序でネストされるかについて心配する必要はありません。getterメソッドが最初に配列yを見つけ、次にその中で要素xを探すことを知っている限り、後方データ構造をそのまま正確に残すことができます。しかし、どのコードが呼び出しgetPoint()ていても、それはわかりません。関心のある2つの座標を知っていれば十分です。


言い換えれば、「プログラムはあなたのコードがどれほどきれいであるかを気にしません!」
OliverSchöning2013年

しかし、逆さまにする以外に、私の保管方法に何か問題がありますか?
OliverSchöning2013年

いいえ、そうは思いません。他の答えはそのように正しいです。私のポイントは、それがあなたをどのように混乱させるのかについてだけです。あなたが尋ねた事実から私はそれを推測しました。実装によってコードが理解しづらくなる場合は、優れたインターフェースの背後にあるその奇妙さをカプセル化し、それを忘れてください。
Seth Battin 2013年

1

それはどうでもいい事です!私はいつもYを最初に書きます(より自然に見えます)。行として配列に行列がある場合、いくつかの最適化を行うこともできます。これの代わりに:

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

あなたはこれを使うことができます:

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

そして、多くの乗算を避けてください!:)


2番目の例の方が優れている点を教えてください。:o JavaScriptでは「実際の」2D配列はありません。配列の配列を作成する必要があります。したがって、2番目の例を使用できるかどうかはわかりません。
オリバーSchöning

w = h = 1000としましょう。最初の例では、1000000の乗算を実行していますが、2番目の例では、1000の乗算のみを実行しています。乗算は非常に困難です。多くのCPUには乗算コマンドさえありません。彼らは加算とビット操作でそれをエミュレートしています。
Ivan Kuckir 2013年

そうですか。しかし、私は自分がそのような繰り返しをしているのを見ていません。鉱山は通常、次のようになります:for(var y ...){array [y] = [] for(var x ...){array [y] [x] = a;}}
OliverSchöningMar

1
はい。しかし、ヒープ上に1000個の新しいJSオブジェクトを作成しています...気にしないでください、おそらくJSにAdobe Photoshopを実装していないので、繰り返しを使用してください:)
Ivan Kuckir
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.