Push into an array of arrays which has an array of arrays

JeFawk :

I currently have an array for a multiplayer web game that looks like so:

[
   [
      "<some value>",
      "<some value>",
      "<some value>",
      [
         [
            <some value>,
            <some value>,
            <some value>,
            <some value>
         ]
      ]
   ]
]

So the myArray[0][2][0] holds info about 1 player.

I use the following code

var TempPlayerArrayToAdd = [<some value>, <some value>, <some value>, <some value>];
myArray[0][2].push(TempPlayerArrayToAdd);

But this results into the error that .push is not a function and I cannot figure out how to use it properly even after checking MDN docs.

The desired result would be

[
   [
      "<some value>",
      "<some value>",
      "<some value>",
      [
         [
            <some value>,
            <some value>,
            <some value>,
            <some value>
         ],
         [
            <some value>,
            <some value>,
            <some value>,
            <some value>
         ]
      ]
   ]
]

Thanks for your time :)

T.J. Crowder :

Ideally, you want to change your data structure to use an array of objects, where each object has a property containing an array of its child objects (children is a common name for this property).

But first, the problem you're actually having: Since your entries may be arrays or non-arrays (strings in your xample), you need to check whether the value at each of the positions you want is an array and, if not, make it one.

So for instance:

let entry = myArray[0];
if (!Array.isArray(entry)) {
    entry = myArray[0] = [entry];
}
entry = entry[2];
if (!Array.isArray(entry[2])) {
    entry = entry[2] = [entry];
}
entry.push(...toAdd); // Or in ES5: entry.push.apply(entry, toAdd);

Live Example:

var myArray = [
   [
      "<some value>",
      "<some value>",
      "<some value>",
      [
         [
            "<some value>",
            "<some value>",
            "<some value>",
            "<some value>"
         ]
      ]
   ]
];

var toAdd = ["<some value>", "<some value>", "<some value>", "<some value>"];

let entry = myArray[0];
if (!Array.isArray(entry)) {
    entry = myArray[0] = [entry];
}
entry = entry[2];
if (!Array.isArray(entry[2])) {
    entry = entry[2] = [entry];
}
entry.push(...toAdd); // Or in ES5: entry.push.apply(entry, toAdd);

console.log(myArray);

You can see how that's problematic, hence my suggestion of using the objects instead:

toAdd = toAdd.map(value => ({value, children: []}));
myArray[0].children[2].children.push(...toAdd);

Live Example:

var myArray = [
    {
        value: null,
        children: [
            {
                value: "<some value>",
                children: []
            },
            {
                value: "<some value>",
                children: []
            },
            {
                value: "<some value>",
                children: []
            },
            {
                value: "<some value>",
                children: [
                    "<some value>",
                    "<some value>",
                    "<some value>",
                    "<some value>"
                ]
            }
        ]
    }
];

var toAdd = ["<some value>", "<some value>", "<some value>", "<some value>"];
toAdd = toAdd.map(value => ({value, children: []}));
myArray[0].children[2].children.push(...toAdd);
/* Or in ES5:
toAdd = toAdd.map(function(value) { return {value: value, children: []}; );
let children = myArray[0].children[2].children;
children.push.apply(children, toAdd);
*/

console.log(myArray);
.as-console-wrapper {
    max-height: 100% !important;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=29744&siteId=1