# Creating nested array automatic

**URL:** <https://discourse.nodered.org/t/creating-nested-array-automatic/33713>\
**Category:** General\
**Created:** [3 October 2020 21:41 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713 "2020-10-03T21:41:59Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ward](https://avatars.discourse-cdn.com/v4/letter/w/439d5e/32.png) [@Ward](https://discourse.nodered.org/u/Ward)\
**Post date:** [3 October 2020 21:41 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/1 "2020-10-03T21:41:59Z")

</div>

Hi,

I'm trying to create a nested array but i don't know the length of the MainArray.

for example:

```auto
MainArray[0] = ArrayNest0[];
MainArray[1] = ArrayNest1[]; 

```

`MainArray[i]= ArrayNesti[]`

I can create the Array i want if i know the length of the MainArray. I thought of making a case function where i fill in all the different ArrayNest on the basis of which MainArray i need to fill.  
But with this methode i need to make alot of var ArrayNest and to be safe, because i need to make sure that i have more then i need.

So my question! Is it possible to create the extra var `ArrayNest[]` automatically when i need them (without declaring them first). Or make the `ArrayNest[]` also variable, something like `ArrayNest($i)[]` with i the extra variable?

Or maybe a better way too approach this problem?

I hope i make some sense. Because i found it hard to explain 😅

Thanks at advance!  
Kind regards,  
Ward

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [3 October 2020 22:24 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/2 "2020-10-03T22:24:10Z")

</div>

There are many javascript properties and methods for working with arrays. Here is a simple example of length and push.

```auto
var fruits = [["Banana", "Orange"], ["Apple", "Mango"]];
fruits[fruits.length] = ["grape", "peach"];
fruits.push(["Kiwi","pear"]);
msg.payload = fruits;
return msg;

```

> **[JavaScript Array length Property](https://www.w3schools.com/jsref/jsref_length_array.asp)**

  

> **[JavaScript Array push() Method](https://www.w3schools.com/jsref/jsref_push.asp)**

---

<div class="post-metadata">

**Author:** ![Ward](https://avatars.discourse-cdn.com/v4/letter/w/439d5e/32.png) [@Ward](https://discourse.nodered.org/u/Ward)\
**Post date:** [4 October 2020 10:18 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/3 "2020-10-04T10:18:22Z")

</div>

@E1cid thanks for the reply.

If i use the push function i need somthing like this:

```auto
msg.startdate = new Date();
var entries = Object.entries(msg.payload);
var entrieslength = entries.length;

var MainArray = [[]];
var PushArray = [];

var i;
var i2 = 0;
var n;
var FirstScan = 0;
var Topic;

for (i=0; i!==10; i++) {
    
    Topic = entries[i][0].split("$");
    
    if (FirstScan === 0) {
        PrevTopic = Topic[0];
        firstscan = 1;
        MainArray[i2][].push(['Parameters','Actual Value','Prev Value','Date Changed','Comment']);
    }
    
    if (Topic[0] !== PrevTopic) {
        i2++;
        MainArray[i2][].push(['Parameters','Actual Value','Prev Value','Date Changed','Comment']);
        PrevTopic = Topic[0];
    }
    
    MainArray[i2][].push([Topic[0],entries[i][1],Math.random(),new Date(),Topic[1]]);
}

msg.payload = MainArray;
return msg;

```

But the problem is Javascript doen't know that syntax that  
`MainArray[i2][].push()`

I tried it with this approach and it works.

```auto
var MainArray = [[]];
var PushArray0 = [];
var PushArray1 = [];

MainArray[0] = PushArray0;
MainArray[1] = PushArray1;
MainArray[i] = PushArrayi;

```

As you can see for every MainArray[i][j] i value i need a new PushArray because i tried it with 1 PushArray and every line in the MainArray gets the same value of the latest PushArray.  
What i find strange! Because i thought that if you store a value in MainArray[0] it's saved in that Array on that spot and if i write the second place or any other the value stored in spot 0 doesn't look back at the var that stored it (if that make sense). I don't have the original code anymore i will try to recreate it and send it over.

That's why my original question (which was a little chaotic) was if i could make of the PushArray(i) variable so the code could be alot smaller like example:

```auto
var MainArray = [[]];
var PushArray($j) = [];
var i;
var j;

MainArray[i].push(PushArray($j));

```

or

```auto
var MainArray = [[]];
var PushArray(1) = [];
var PushArray(2) = [];

var PushArray(n) = [];
var i;
var j;

if (j<=n) MainArray[i].push(PushArray($j));

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [4 October 2020 10:38 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/4 "2020-10-04T10:38:03Z")

</div>

> [@Ward](#):
>
> `MainArray[i2][].push()`

For push you provide a reference to the array to which you want to push, so that should be  
`MainArray.push([...])`  
or, if you have an already constructed array you want to add, then  
`MainArray.push(pushArray)`

Also your declaration of MainArray should be  
`var MainArray = []`  
as it is an array to which you are going to push contained arrays.

The convention in javascript is to start variables with a lower case letter, so if you want to adopt the convention then mainArray would be better.

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [4 October 2020 12:58 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/5 "2020-10-04T12:58:47Z")

</div>

```auto
var MainArray =[];
\\ to add to this array
MainArray.push(["an array"]);
\\ this will add an arry element at the end of MainArray

\\to add to a nested array
MainArray[2].push(["something"]);
\\ this wiill add an element to element 2 of MainArray

```

---

<div class="post-metadata">

**Author:** ![Ward](https://avatars.discourse-cdn.com/v4/letter/w/439d5e/32.png) [@Ward](https://discourse.nodered.org/u/Ward)\
**Post date:** [4 October 2020 17:04 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/6 "2020-10-04T17:04:36Z")

</div>

@Colin @E1cid Thanks for the info with your explanation i found what i did wrong.

My code is here for the ones interested

```auto
msg.startdate = new Date();
var entries = Object.entries(msg.payload);
var entrieslength = entries.length;

msg.entries = entries;

var pushArray = [];
var dataArray = [];

var i;
var firstScan = 0;
var topic;
var prevTopic = 0;
var dataLength;

for (i=0; i!==entries.length; i++) {
    
    topic = entries[i][0].split("$");
    
    msg.topic0 = topic[0];
    msg.topic1 = topic[1];
    msg.prevtopic = prevTopic;
    
    if (firstScan === 0) {
        prevTopic = topic[0];
        firstScan = 1;
        dataArray.push(['Parameters','Actual Value','Prev Value','Date Changed','Comment']);
        i1++;
        msg.i1 = i1;
    }
    
    if (topic[0] !== prevTopic) {
        pushArray.push([dataArray]);
        datalength = dataArray.length;
        dataArray = dataArray.splice(0,dataLength);
        dataArray.push(['Parameters','Actual Value','Prev Value','Date Changed','Comment']);
        prevTopic = topic[0];
    }
    dataArray.push([topic[0],entries[i][1],Math.random(),new Date(),topic[1]]);
}
pushArray.push([dataArray]);
msg.payload = pushArray;
return msg;

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [4 October 2020 20:58 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/7 "2020-10-04T20:58:13Z")

</div>

Does that do what you want, several aspects look a bit odd? Have you looked carefully at what comes out and checked it is ok?

For example, as far as I can see dataArray gets one or more elements added to it each time round the loop, so it is continually getting bigger. Also each time round, if `topic[0] !=== prevTopic` you push an element onto pushArray. which is an array of one element, where that element is dataArray. But since dataArray is itself getting longer each time you keep adding the same data again, plus a bit more. Then at the end you push dataArray, again in a one element array (ie [dataArray]) to pushArray again before returning it in msg.payload.

A couple of minor things, mainArray appears to be redundant, and I think it is preferable to code the for statement as  
`for (i=0; i<entries.length; i++) {`  
That makes it much less likely that a minor code error will cause a (virtually) endless loop.  
You might find that the code would be simplified if you used `for .. in` along with hasOwnProperty rather than Object.entries.  
I think `msg.i1` will allways be 1, but I may be missing something.  
Finally, does it matter which order the properties are enumerated? The order of property enumeration is not guaranteed.

---

<div class="post-metadata">

**Author:** ![Ward](https://avatars.discourse-cdn.com/v4/letter/w/439d5e/32.png) [@Ward](https://discourse.nodered.org/u/Ward)\
**Post date:** [4 October 2020 21:37 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/8 "2020-10-04T21:37:49Z")

</div>

@Colin

My output is:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/2/e28ad6ae19e2fe839cc683ab0c465cc46fdc2f6b.png)

It does it job but if i can simplied it all the better. 1 thing i was looking into.  
The dataArray was put in a extra array so if i need to collect the right Setpoints by example:  
P2.0-Setpoints (see picture) i need to select msg.payload = pushArray[1][0]

And for the rest  
mainArray was indeed redundant. Thought originally that i needed it and forgot to delete it. And the msg.i1 and msg.i2 was for debug purpuses. But i edited the previous post so that's is gone.

And i didn't know of the `for .. in` function. Definitely going to look into it.

Kind regards  
Ward

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [5 October 2020 08:14 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/9 "2020-10-05T08:14:14Z")

</div>

Notice how each element of the payload array is itself an array of 1 element, which contains the data you want. You can remove the array[1] level by changing the `pushArray.push([dataArray])` statements to `pushArray.push(dataArray)`.

The incantation to use with `for .. in` is something like

```auto
for (const prop in msg.payload) {
  if (msg.payload.hasOwnProperty(prop)) {
    // prop now contains the key of one of the properties of the payload
    // and the value of the property is msg.payload[prop]
    // so for example if the payload included someprop: 73 then prop would be
    // "someprop* and msg.payload[prop] would be 73
  }
}

```

The reason for using hasOwnProperty is that the object in msg.payload might contain properties that are actually part of some underlying object that the payload object is derived from. Using hasOwnProperty ensures you only get properties that are part of the top level object.

---

<div class="post-metadata">

**Author:** ![Ward](https://avatars.discourse-cdn.com/v4/letter/w/439d5e/32.png) [@Ward](https://discourse.nodered.org/u/Ward)\
**Post date:** [5 October 2020 10:51 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/10 "2020-10-05T10:51:12Z")

</div>

> [@Colin](#):
>
> Notice how each element of the payload array is itself an array of 1 element, which contains the data you want. You can remove the array[1] level by changing the `pushArray.push([dataArray])` statements to `pushArray.push(dataArray)` .

This was indeed the problem, thanks.

for the `For ... in` i going to adress it now.

But a followup question. Later in the flow i want to alter some values in the Array.

First i take 2 copies (msg.payload1 & msg.payload2) of the mainArray (see earlier post) which i have put in msg.parametersRead.

But if i now change some values. It's change the values of the both copies and the original. See Picture. (I don't show in the picture but msg.parametersRead. is also the same and the original values where different.)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/3/83e036793985b82b7f6f7e22833fe76d2618e0a5.png)

Why are they linked to each other?

PS: Also tried the push function. instead of msg.payload1 = msg.parametersRead;

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [5 October 2020 11:04 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/11 "2020-10-05T11:04:54Z")

</div>

That is because of the way javascript handles objects. When you assign an object to a variable it doesn't make a copy, it just sets the variable to point to the object in memory, so if you do that and then change the underlying object both variables are still pointing to the same object so they both change. If you want to make a copy (or clone) of the object then you can use  
`someVar = RED.util.cloneMessage(originalVar)`

---

<div class="post-metadata">

**Author:** ![Ward](https://avatars.discourse-cdn.com/v4/letter/w/439d5e/32.png) [@Ward](https://discourse.nodered.org/u/Ward)\
**Post date:** [6 October 2020 12:41 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/12 "2020-10-06T12:41:18Z")

</div>

Oke that make sense then. With the `someVar = RED.util.cloneMessage(originalVar)` it works like a charm.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [5 December 2020 12:41 UTC](https://discourse.nodered.org/t/creating-nested-array-automatic/33713/13 "2020-12-05T12:41:20Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
