2013-07-21 6 views
14

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

Во-первых, я попытался инициализировать пустой массив 10x10x10, используя var theArray = new Array(10, 10 10), но вместо этого он создал только 1-мерный массив с 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)); 
+0

Язык программирования Java имеет 'ИНТ [] [] вещи = new int [10] [10] ', но я не знаю никакой подобной конструкции в JavaScript. –

+0

Возможный дубликат [Как создать двумерный массив в JavaScript?] (Http://stackoverflow.com/questions/966225/how-can-i-create-a-two-dimensional-array-in-javascript) – Lion

+2

@Lion Нет, этот вопрос задает вопрос о том, как инициализировать массивы произвольно многих измерений, а не только 2 измерения. –

ответ

6

адаптировано из this answer:

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); дает 3-мерный массив одинаковой длины.
  • var weirdArray = createArray(34,6,42,2); Дает 4-мерный массив неравных длин.
+1

+1 для использования фрагмента – raam86

+0

вы можете упростить свое 'while', используя тот, который я сделал в своем ответе – naomik

+0

славный !! его слишком эффективный! хорошее решение для хорошей проблемы –

1

Вот мой взгляд на проблему: 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 массиве неопределенных значений.

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

3
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"'s yields 16 of them 

демо http://jsfiddle.net/WPrs3/

+0

Хорошая работа, два младших nitpicks: callee устарел, и лучше перемещать срез из цикла. – georg

+0

@ thg435 хорошие баллы – goat

0

Чем больше размера у вас есть, тем больше у вас есть интерес, используя один единственный плоский массив и поглотитель/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)'); 

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

0

Более лаконичная версия коды @ Крис:

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/

0

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

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

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

Смежные вопросы