2016-07-25 5 views
1

У меня есть 2d-массив, содержащий до [32] [32] записи. И я хотел бы, чтобы преобразовать его из чего-то вроде этого:Преобразование многомерного массива в объект

[ 
    null, 
    null, 
    null, 
    null, 
    null, 
    null, 
    [null, null, null, null, null, null, null, null, null, null, "player1"], 
    [null, null, null, null, null, "player2"] 
] 

к

{ 
    "6": {"10":"player1"}, 
    "7": {"5":"player2"} 
} 

Так что это был бы мой массив:

var gameField = []; 
gameField[6] = []; 
gameField[6][10] = "player1"; 
gameField[7] = []; 
gameField[7][5] = "player2"; 

Теперь я попытался использовать это:

var obj = {} 
obj = Object.assign({},gameField); 
console.log(JSON.stringify(obj)); 

но он работал только для внешнего массива, внутренние массивы не были затронуты:

{ 
    "6": [null, null, null, null, null, null, null, null, null, null, "player1"], 
    "7": [null, null, null, null, null, "player2"] 
} 

Что бы самый короткий путь, чтобы сделать это правильно?

+0

Можете ли вы объяснить, что вы пытаетесь достичь? – Rajesh

+1

Это кажется очень плохой структурой, до * и * после. Клавиши динамических объектов в основном трудно использовать. Почему бы вам не использовать что-то более чистое, например, '[{player: 'player1', numberOfX: 10}, {player: 'player2', numberOfX: 5}]'. – str

+0

Структура немного сложнее в реальности. Это больше, чем просто игроков. То, что я хочу достичь, - просто преобразовать массив 2d в объект, который использует индексы массива в качестве ключей. Чтобы я мог избавиться от всех нулевых значений массива. – Forivin

ответ

4

Вы можете перебирать элементы в массиве, а затем рекурсию, если находится элемент сам по себе является массивом (проверить с помощью Array.isArray)

function populateFromArray(array) { 
    var output = {}; 
    array.forEach(function(item, index) { 
    if (!item) return; 
    if (Array.isArray(item)) { 
     output[index] = populateFromArray(item); 
    } else { 
     output[index] = item; 
    } 
    }); 
    return output; 
} 

console.log(populateFromArray(input)); 

Это приводит к:

[object Object] { 
    6: [object Object] { 
    10: "player1" 
    }, 
    7: [object Object] { 
    5: "player2" 
    } 
} 

См working jsBin

Примечание: вы можете сделать это меньше кода, но меньше кода не всегда лучше!

+0

Ницца, он работает. Можете ли вы немного рассказать о «меньше кода»? – Forivin

+0

Если вы видите ответ от @redu, то у вас есть прекрасный пример. Это гораздо меньше кода, но, на мой взгляд, гораздо труднее понять. –

+0

Хорошая вещь о вашем коде - это не сломается, если вы помещаете объекты вместо строк в исходный массив. – Forivin

3

Array.prototype.reduce() кажется идеальным для этого. Вы можете сделать следующее:

var dataArr = [null,null,null,null,null,null,[null,null,null,null,null,null,null,null,null,null,"Player1"],[null,null,null,null,null,"player2"]], 
 
    dataObj = dataArr.reduce((p,c,i) => (Array.isArray(c) && (p[i] = {[c.length-1]:c[c.length-1]}),p),{}); 
 
console.log(dataObj);

+0

Аккуратно, мне это нравится! – Forivin

+0

Хотя если я использую такой объект, как '{id: 0, name: 'Player1'}' вместо "player1", я больше не могу получить доступ к свойству после преобразования. – Forivin

+0

@Forivin ... Извините, что был добавлен дополнительный набор скобок, которые я упустил, и в результате появился массив '['player1"] 'вместо строки' 'player1" '. Теперь все должно быть хорошо. – Redu

1

Вы могли бы использовать эту рекурсивную функцию, используя ES6 код:

var data = [null,null,null,null,null,null,[null,null,null,null,null,null,null,null,null,null,"player1"],[null,null,null,null,null,"player2"]]; 
 

 
function convert(data) { 
 
    return Array.isArray(data) 
 
     ? data.reduce((obj, el, i) => (el && (obj[i] = convert(el)), obj), {}) 
 
     : data; 
 
} 
 

 
var obj = convert(data); 
 

 
console.log(obj);

Это также будет работать, когда ваш входной массив вложен глубже, чем 2 уровни. Он не требует, чтобы непустые элементы находились в конце их (под) массива, а также не было только одного ненулевого элемента в (под) массиве.

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