将多维数组转换为对象

问题描述:

我有一个最多[32] [32]条目的2d数组。 我想从这样的转换:将多维数组转换为对象

[ 
    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

您可以在阵列中的项目迭代,然后递归如果位于项目本身是一个数组(检查使用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

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

您可以使用此递归函数,使用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嵌套更深水平。它不要求非null元素位于其(子)数组的末尾,也不要求每个(子)数组只有一个非null元素。