Tablice w JavaScript mają własnych dziwactw, że nie można oczekiwać, jeśli pochodzą z innych języków. Dwa ważne dla twojego przypadku użycia to:
- Nie możesz bezpośrednio zadeklarować tablic wielowymiarowych w JavaScript.
- Przy ustawianiu rozmiaru macierzy przy tworzeniu jest niewielka korzyść pod względem wydajności (i braku dodatkowego bezpieczeństwa).
W przeciwieństwie do innych języków, JavaScript nie przydzieli bloku pamięci dla pełnej tablicy. (Nie wie, jakie obiekty będą umieszczane w każdej komórce, , a zatem ile całkowitej pamięci będzie potrzebować.) Zamiast tego, cały argument size
dla Array()
robi dla ciebie zestaw tablic Właściwość length
.
W ogólnym przypadku, 2d tablicy, którą proponujemy:
Utwórz tablicę "top", np .:
var i // the first-order index in a
, j // the second order index in a
, a = []
Initialize elementów tablicy, ile potrzeba. Nazywa się to lazy initialization,i w tym przypadku wymaga to po prostu sprawdzenia, czy a[i]
istnieje zanim spróbujemy przypisać coś do a[i][j]
, np.:
if (!a[i]) a[i] = []
W angielskim powyższe stwierdzenie brzmi: „Jeśli element i-ty z a
jest«falsy»przypisać pustą tablicę do elementu i-tej”.
Wreszcie, należy przypisać wartość rzeczywistą do multideminsional tablicy:
a[i][j] = 'whatever'
Twoim przypadku, wiesz wartości wyprzedzeniem, więc można zainicjować każdego elementu z góry. (Jeśli nie jesteś przesłanianie większość elementów, jednak leniwy realizacja może być lepiej; patrz poniżej.)
var x, x_length = 100
, y, y_length = 100
, map = []
// Don't be lazy
for (x = 0; x < x_length; x++) {
map[x] = []
for (y = 0; y < y_length; y++) {
map[x][y] = 'grass.gif|ongrass.gif|collision.gif|above.gif'
}
}
Jak niektórzy mówili inni, tablicą z 100 elementów został indeksy ponumerowane od zero do dziewięćdziesiąt dziewięć, więc porównanie poniżej jest najbardziej odpowiednie tutaj.
Dla odniesienia, oto implementacja, która używa leniwego inicjowania. Poszedłem z interfejsem funkcji zamiast bezpośredniego dostępu do tablicy; jest dłuższy i bardziej złożony, ale także bardziej kompletny.
Wzorzec inicjalizacji, którego tu użyłem, nazywa się immediately invoked function expression. Jeśli jeszcze tego nie widziałeś, to jest to jeden z bardziej użytecznych wzorców JavaScriptu i warto poświęcić trochę czasu, aby go zrozumieć.
var map = (function (x_length, y_length, v_default, undefined) {
// Unless v_default is overwritten, use ...
v_default = v_default || 'grass.gif|ongrass.gif|collision.gif|above.gif'
// Private backing array; will contain only values for a[x][y]
// that were explicitly set.
var a = []
// Private helper function.
// - Returns `true` if `x` is between `0` and `x_length - 1`
// and `y` is between `0` and `y_length - 1`.
// - Returns `false` otherwise.
function valid (x, y) {
return (x >= 0
&& x < x_length
&& y >= 0
&& y < y_length)
}
// Private helper function.
// - Returns `true` if a[x][y] has been set().
// - Returns `false` otherwise.
function exists (x, y) {
return !!a[x] && !!a[x][y]
}
// Private getter
// - Returns the value of a[x][y] if it has been set().
// - Returns `undefined` if the point (x,y) is invalid.
// - Returns `v_default` otherwise.
function get (x, y) {
if (!valid(x, y)) return undefined
else if (exists(x, y)) return a[x][y]
else return v_default
}
// Private setter
// - Returns the value set on success.
// - Returns `undefined` on failure
function set (x, y, v) {
if (valid(x, y)) {
// We're being lazy
if (!a[x]) a[x] = []
a[x][y] = v
return a[x][y]
}
return undefined
}
// Return an interface function.
// - Pass the function three arguments, (x, y, v), to set a[x][y] = v
// - Pass the function two arguments, (x, y), to get a[x][y]
return function (x, y, v) {
if (arguments.length > 2) {
return set(x, y, v)
} else {
return get(x, y)
}
}
})(100, 100)
Kiedy wpadłem wyżej w węźle, następujące testy drukowane wartości rozsądni:
// Invalid invocations
console.log('map() : %s', map())
console.log('map( 0) : %s', map(0))
console.log('map(-1, 0) : %s', map(-1,0))
console.log('map( 0, -1) : %s', map(0, -1))
console.log('map(-1, -1) : %s', map(-1, -1))
// Valid invocations
console.log('map( 0, 0) : %s', map(0, 0))
console.log('map(99, 99) : %s', map(99, 99))
console.log('map( 1, 1) : %s', map(1,1))
console.log('map( 1, 1, "foo") : %s', map(1,1, 'foo'))
console.log('map( 1, 1) : %s', map(1,1))
* Dlaczego tak się dzieje * Ponieważ 'world_map_array [i]' 'undefined' jest w pewnym momencie?. Jeśli tablica ma długość, powiedzmy "3", wówczas indeksy to '0',' 1', '2'. Ponadto, jeśli nigdy nie przypisałeś wartości do indeksu, będzie to "niezdefiniowana". –
jak to naprawić? – user1406186
co próbuję zrobić, to utworzyć dwuwymiarową tablicę do reprezentowania mapy kafelków. na przykład "[0,0] [1,0] [2,0] [0,1] [1,1] [2,1] [0,2] [1,1] [2,2] ' – user1406186