2016-09-05 17 views
7

Opracowałem bibliotekę aC#, która była używana w 3 projektach, które przekazują ten konkretny fragment kodu, chociaż nadal potrzebuję użyć tego kodu w javascriptu, więc im to przeniesię, Rzecz w tym, że nie mogę powtórzyć tej samej logiki, na przykład, myślałem o tym przez kilka dni, nie mogłem znaleźć odpowiedzi.Przenoszenie C# 3D Array do JS 3D Array

W bibliotece C# mam tablicę 3D, która jest trochę podobna do właściwości głównej w aplikacji i nie mogę wymyślić, jak wykonać tę pracę w środowisku JS.

Na przykład mam ten fragment kodu:

public Obj[,,] objs = new Obj[18, 14, 8]; 

W którym chciałbym przeznaczyć obiektów w każdej pozycji i próbuje portu, do javascript, pozornie skutkowałoby:

var 3dArr = new Array(); 
    3dArr[0] = new Array(); 
    3dArr[0][0] = new Array(); 

Czy to nie zawsze utrzymywałoby obiekt tablicy w pierwszej pozycji i gdybym ustawił coś innego, straciłbym całą tablicę? Czy jestem w błędzie?

+1

Jesteś poprawne. Nie ma wbudowanego typu, który reprezentuje wielowymiarowe tablice w JS. – zerkms

+1

Możesz zbudować go w JS albo w postaci zagnieżdżonych tablic, myślę, że to opisałoby to w C# 'public Obj [Obj [Obj []]] objs', albo utworzysz adapter z API, który zajmuje n-wymiarowe pozycje i mapy je do jednowymiarowych kluczy/wskaźników na wewnętrznej strukturze danych. jak 'key = [x, y, z] .join ('::')' lub 'index = (x * 14 + y) * 8 + z'. Pewnie + sprawdzenie, czy pozycja nie jest poza granicami. – Thomas

Odpowiedz

2

W chwili pisania tego artykułu w JavaScript nie ma funkcji językowej, która byłaby bardzo podobna do wielowymiarowych tablic w języku C#. Nie zaleca się również narażania zwykłych tablic na używanie całej aplikacji, ponieważ mogłoby to łatwo omyłkowo uszkodzić cały kod, pisząc do tablicy coś, czego nie powinno się trzymać.

Należy jednak względnie łatwo enkapsulować potrzebną tablicę do prostej nowej klasy, np. Array3d w poniższym kodzie:

/***** CODE OF THE ARRAY *****/ 
 
function Array3d(width, height, depth, type) { 
 
    this.width = width; 
 
    this.height = height; 
 
    this.depth = depth; 
 
    this.type = type; 
 
    this.array = new Array(width * height * depth); 
 
} 
 

 
Array3d.prototype = { 
 
    get: function(x, y, z) { 
 
     return this.array[calcIndex(this, x, y, z)]; 
 
    }, 
 
    set: function(x, y, z, item) { 
 
     if (!(item instanceof this.type)) { 
 
      throw new Error(item + ' is not instance of ' + this.type + '.'); 
 
     } 
 
     this.array[calcIndex(this, x, y, z)] = item; 
 
    } 
 
}; 
 

 
function calcIndex(array3d, x, y, z) { 
 
    return x + array3d.width * y + array3d.width * array3d.height * z; 
 
} 
 

 
/***** USAGE CODE *****/ 
 
function Something(i) { 
 
    this.index = i; 
 
} 
 

 
var array3d = new Array3d(10, 11, 12, Something); 
 
var something = new Something(11); 
 
array3d.set(4, 0, 0, something); 
 
var gettingBack = array3d.get(4, 0, 0); 
 
if (gettingBack === something) { 
 
    console.log('1: Works as expected'); 
 
} 
 
else { 
 
    console.error('1: Not expected ' + gettingBack); 
 
} 
 
gettingBack = array3d.get(0, 0, 4); 
 
if (gettingBack == null) { 
 
    console.log('2: Works as expected'); 
 
} 
 
else { 
 
    console.error('1: Not expected ' + gettingBack); 
 
}

+1

Tak, zastanawiałem się nad obliczeniem pozycji obiektu na podstawie współrzędnych x, yi z, chciałem tylko upewnić się, że jestem w 100% pewien, że nie można tego osiągnąć za pomocą tablicy [x, y, z]. Twoja odpowiedź wydaje się być właściwą drogą. Zrobię to i przetestuję to. Dzięki! –

1

spróbować tego ...

Array3d = function (width, height, depth, defaultValue) { 
    width = width || 1; 
    height = height || 1; 
    depth = depth || 1; 
    defaultValue= defaultValue|| 0; 
    var arr = []; 
    for (var i = 0; i < width; i++) { 
     arr.push([]); 
     for (var j = 0; j < height; j++) { 
     var last = arr[arr.length - 1]; 
     last.push([]); 
     for (var k = 0; k < depth; k++) { 
      last[last.length - 1].push(defaultValue); 
     } 
     } 
    } 
    return arr; 
} 
console.log(new Array3d(3, 5, 2, 0)); 

więc określić width, height, depth (te trzy domyślne do 1), a defaultValue (domyślnie zero) i można nim manipulować tak, jak w dowolnej tablicy javascript ...

1

w JavaScript tablica 3D utworzone jako szereg tablic tablic:

var 3DArr = [[[],[],[]],[[],[],[]],[[],[],[]]]; 

teraz 3DArr jest szereg tablic wewnątrz niego, przy czym każdy zawierają również tablicę.Więc można zrobić (na przykład):

3DArr[0][1].push(10); 
console.log(3DArr); // [[[],[10],[]],[[],[],[]],[[],[],[]]] 
0

W nowszych przeglądarek tablicy tablic mogą być inicjowane z Array.from:

a = Array.from(Array(3),() => Array.from(Array(3),() => Array(3).fill(0))) 
 

 
console.log(JSON.stringify(a))

Na marginesie, JavaScript „Array "jest bardziej podobny do specjalnego Dictionary, który używa swoich klawiszy całkowitych:

a = [] 
 
a['1'] = 2 
 
a.b = 'c' 
 
a[3.14] = Math.PI 
 

 
console.log(a)     // "[undefined, 2]" 
 
console.log(a[1], a.b, a['3.14']) // "2 c 3.141592653589793"

więc można przypisać wartości do niego przed inicjalizacji wszystkie "wymiary":

function set(a, x, y, z, v) { 
 
    if(!a[x]) a[x] = [] 
 
    if(!a[x][y]) a[x][y] = [] 
 
    a[x][y][z] = v 
 
} 
 

 
a = [] 
 
set(a, 1, 2, 3, 4) 
 

 
console.log(a)