Есть ли более сжатый способ инициализации пустых многомерных массивов?

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

Сначала я попытался инициализировать пустой массив 10x10x10 с помощью var theArray = new Array(10, 10 10), но вместо этого он создал только одномерный массив с 3 элементами.

Я выяснил, как инициализировать пустой массив 10x10x10 с помощью вложенных for-loops, но очень утомительно записывать инициализатор массива таким образом. Инициализация многомерных массивов с использованием вложенных for-loops может быть довольно утомительной: существует ли более краткий способ установки размеров пустых многомерных массивов в JavaScript (с произвольным числом измерений)?

//Initializing an empty 10x10x10 array:
var theArray = new Array();
for(var a = 0; a < 10; a++){
    theArray[a] = new Array();
    for(var b = 0; b < 10; b++){
        theArray[a][b] = new Array();
        for(var c = 0; c < 10; c++){
            theArray[a][b][c] = 10
        }
    }
}

console.log(JSON.stringify(theArray));

Ответ 1

Адаптировано из этого ответа:

function createArray(length) {
  var arr = new Array(length || 0),
      i = length;

  if (arguments.length > 1) {
    var args = Array.prototype.slice.call(arguments, 1);
    while(i--) arr[i] = createArray.apply(this, args);
  }        
  return arr;
 }

Просто вызовите с аргументом для длины каждого измерения. Примеры использования:

  • var multiArray = createArray(10,10,10); Дает трехмерный массив равной длины.
  • var weirdArray = createArray(34,6,42,2); Дает 4-мерный массив неравных длин.

Ответ 2

function multiDimArrayInit(dimensions, leafValue) {
    if (!dimensions.length) {
        return leafValue;
    }
    var arr = [];
    var subDimensions = dimensions.slice(1);
    for (var i = 0; i < dimensions[0]; i++) {
        arr.push(multiDimArrayInit(subDimensions, leafValue));
    }
    return arr;
}


console.log(multiDimArrayInit([2,8], "hi")); // counting the nested "hi" yields 16 of them

demo http://jsfiddle.net/WPrs3/

Ответ 3

Вот мой вопрос: nArray служебная функция

function nArray() {
    var arr = new Array();
    var args = Array.prototype.slice.call(arguments, 1);
    for(var i=0;i<arguments[0];i++) {
        arr[i] = (arguments.length > 1 && nArray.apply(this, args)) || undefined;
    }
    return arr;
}

Пример использования:

var arr = nArray(3, 3, 3);

Результаты в массиве 3x3x3 значений undefined.

Запуск кода с некоторыми тестами также доступен в виде скрипта здесь: http://jsfiddle.net/EqT3r/7/

Ответ 4

Чем больше у вас размеров, тем больше у вас интерес к использованию одного плоского массива и функции getter/setter для вашего массива.
Потому что для [d1 X d2 X d3 X.. X dn] вы создадите d2 * d3 *... * dn массивы вместо одного, и при доступе вы сделаете n косвенным, а не 1.

Интерфейс будет выглядеть так:

var myNArray = new NArray(10,20,10);
var oneValue = myNArray.get(5,8,3);
myNArray.set(8,3,2, 'the  value of (8,3,2)');

реализация зависит от вашего предпочтения фиксированного размера n-мерный массив или массив, способный нажать/поп и т.д.

Ответ 5

Более краткий вариант кода @chris:

function multiDim (dims, leaf) {
  dims = Array.isArray (dims) ? dims.slice () : [dims];
  return Array.apply (null, Array (dims.shift ())).map (function (v, i) {
    return dims.length 
      ? multiDim (dims, typeof leaf == 'string' ? leaf.replace ('%i', i + ' %i') : leaf)
      : typeof leaf == 'string' ? leaf.replace ('%i', i) : leaf;
  });      
}

console.log (JSON.stringify (multiDim ([2,2], "hi %i"), null, '  ')); 

Производит:

[
  [
    "hi 0 0",
    "hi 0 1"
  ],
  [
    "hi 1 0",
    "hi 1 1"
  ]
]

В этой версии вы можете передать первый аргумент как число для одномерного массива. Включение %i в значение листа даст значения индекса в значениях листа.

Играйте с ним по адресу: http://jsfiddle.net/jstoolsmith/r3eMR/

Ответ 6

Очень простая функция, сгенерируйте массив с любым количеством измерений. Укажите длину каждого измерения и контент, который для меня обычно равен

function arrayGen(content,dims,dim1Len,dim2Len,dim3Len...) {
  var args = arguments;
  function loop(dim) {
    var array = [];
    for (var a = 0; a < args[dim + 1]; a++) {
      if (dims > dim) {
        array[a] = loop(dim + 1);
      } else if (dims == dim) {
        array[a] = content;
      }
    }
    return array;
  }
  var  thisArray = loop(1);
  return thisArray;
};

Я использую эту функцию очень часто, это экономит много времени