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!");
    }
}

Это так безумно? Я хотел бы перейти на обычную практику, чтобы мне было легче строить свою игру и не делать постоянных переключений.

Так почему же X до Y?

Редактировать: Вот еще один пример, и, вероятно, главная причина моего замешательства: 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) на декартовой плоскости.
Вон Хилтс

Я так думаю, но посмотрите на мой новый пример массива. Мне это кажется более правильным
Оливер Шенинг,

Ответы:


8

Нет, если это работает для вас, вы не делаете это неправильно. Если вы хотите переключиться, чем это сделать. Порядок обработки строк / столбцов иногда произвольный, иногда нет. Какой порядок вы используете, полностью зависит от используемого вами алгоритма.

Есть несколько разных комбинаций для обработки X, Y. Вам решать, какой из них подходит для вашего алгоритма. В случае, когда каждая итерация независима от любой другой, вы можете выбрать, какую из них вы хотите. Вы можете переключаться, который находится во внутреннем цикле, и вы также можете переключаться, если циклы переходят от минимального к максимальному или от максимального к минимальному.

Я предполагаю, что по умолчанию:

for xmin to xmax
    for ymin to ymax

потому что это часто, как данные расположены в памяти. (Не обязательно верно для всех языков, так как порядок индекса может измениться).

Например, массив A[3][3]( A[X][Y]):

введите описание изображения здесь

Когда yзначение находится во внутреннем цикле, сначала увеличивается, а затем «переворачивается», чтобы увеличить xзначение. Кроме этого, (X, Y) является стандартным способом написать это в математике.


Приветствия, ну, это просто "выглядит правильно", когда я строю Grid:
Оливер Шенинг

4

Вы делаете это неправильно ... вроде. Неправильно, что вы делаете, это коррелирует порядок, в котором записываются координаты, с порядком, в котором циклы вложены. Это совершенно разные идеи!

Точнее говоря, неправильно то, что ваша система координат сильно (и хрупко) связана с вашей реализацией вашего хранилища данных. Это означает, что вы разрабатываете плохой код с точки зрения ОО. Хранилище данных должно быть непрозрачным для того, кто его использует, и тому, кто его использует, не должно волновать, как хранятся данные. Пользователь данных должен знать только то, как получить необходимую ему информацию.

Что вам нужно сделать, так это найти способ абстрагировать структуру данных вашего вложенного массива и спрятать ее таким способом getPoint(x,y). Тогда вам не нужно беспокоиться о том, какой массив вложен в каком порядке. Вы можете оставить свою структуру данных в обратном направлении точно такой, какая она есть, если ваш метод получения знает, что сначала нужно найти массив y, а затем искать в нем элемент x. Но какой бы код ни вызывал, getPoint()он этого не знает. Нужно знать только две координаты, которые его интересуют.


Другими словами: «Программам все равно, насколько хорош ваш код!»
Оливер Шенинг

Но есть ли что-то плохое в моем способе хранения, кроме перевернутого?
Оливер Шенинг,

Нет, я так не думаю; другие ответы верны в этом смысле. Моя точка зрения только о том, как это вызывает у вас путаницу, что я понял из того, что вы спросили. Если ваша реализация делает ваш код трудным для понимания, тогда заключите эту странность в хороший интерфейс и забудьте об этом.
Сет Баттин

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;
    }
}

и избегайте большого умножения! :)


Не могли бы вы сказать мне, что ваш второй пример лучше? : o В JavaScript нет «настоящих» 2D-массивов, вам нужно создать массив массивов. Поэтому я не знаю, смогу ли я использовать второй пример.
Оливер Шенинг,

Допустим, w = h = 1000. В первом примере вы делаете до 1000000 умножений, в то время как во втором примере вы делаете только 1000 умножений. Умножение очень сложно, многие процессоры даже не имеют команды умножения. Они эмулируют это с помощью сложения и битовых операций.
Иван Кукир

Понимаю. Но я просто не вижу себя в такой итерации. Мои обычно выглядят так: for (var y ...) {array [y] = [] for (var x ...) {array [y] [x] = a;}}
Оливер Шёнинг,

1
Да, конечно. Но вы создаете 1000 новых объектов JS в куче ... о, неважно, вы, вероятно, не внедряете Adobe Photoshop в JS, так что продолжайте использовать свои итерации :)
Иван Кукир
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.