# Help - push an array into array simple question

**URL:** <https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577>\
**Category:** Coding Questions\
**Created:** [August 5, 2021, 4:17am UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577 "2021-08-05T04:17:32Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![atagger](https://avatars.discourse-cdn.com/v4/letter/a/d6d6ee/32.png) [@atagger](https://discourse.processing.org/u/atagger)\
**Post date:** [August 5, 2021, 4:17am UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/1 "2021-08-05T04:17:32Z")

</div>

I’m racking my head not understanding why this doesn’t work.

i was expecting the sampleBuffer array to become a length 32 array containing 32 arrays each with 3 random numbers. Instead I get a length 32 array of 32 arrays with 3 identical numbers. What am I doing wrong?

```auto
let sampleBuffer=[];
let bandsEnergy=[];

function setup() {

}

function draw() {

      for(let i=0; i<3; i++) {
        bandsEnergy[i] = random(10);
      }

      sampleBuffer.push(bandsEnergy);

      if(sampleBuffer.length==32) {

        console.log(sampleBuffer);
        sampleBuffer.splice(0,1);

      }

  }

```

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [August 5, 2021, 6:07am UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/2 "2021-08-05T06:07:43Z")

</div>

> [@atagger](#):
>
> ` i<3`

Your loop only runs 3 times.

You probably want 32 there, not 3.

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [August 5, 2021, 6:22am UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/3 "2021-08-05T06:22:54Z")

</div>

Is it your intent to `push` a reference or a copy here?:

```
      sampleBuffer.push(bandsEnergy);

```

The above will `push` a reference to `bandsEnergy` onto `sampleBuffer`.

For a copy of it instead, there are various possible solutions. One of them is to do this:

```
      sampleBuffer.push(bandsEnergy.slice(0, 3));

```

Try that, then check the contents of `sampleBuffer`.

---

<div class="post-metadata">

**Author:** ![atagger](https://avatars.discourse-cdn.com/v4/letter/a/d6d6ee/32.png) [@atagger](https://discourse.processing.org/u/atagger)\
**Post date:** [August 5, 2021, 6:37am UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/4 "2021-08-05T06:37:43Z")

</div>

All I want to do is push an array of numbers into another array and then reference those numbers to make a calculation. Something is wrong. The splice just removes the last array from the bunch. This is an example of what I want it to do that I did after I posted. Unfortunately this method is not working in my main program. I don’t understand what the problem is. Passing an array into another array should be fine to do, as it’s an object. Not sure why this second example works by putting the array inside an object, and then I have to use something like sampleBuffer[0].band[x]. Maybe I need to make a 2d array. I’ve never had such an annoying problem in p5.

```auto
var sampleBuffer=[];
var bandsEnergy=[];

function setup() {

}

function draw() {

      for(let i=0; i<3; i++) {
        bandsEnergy[i] = random(10);
      }
      var b = { band: bandsEnergy };

      sampleBuffer.push(b);

      if(sampleBuffer.length==32) {

        //console.log(sampleBuffer);
        sampleBuffer.splice(0,1);

      }
      console.log(sampleBuffer);

  // console.log(sampleBuffer[0].band.length);

  }

```

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [August 5, 2021, 6:58am UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/5 "2021-08-05T06:58:39Z")

</div>

> [@atagger](#):
>
> i was expecting the sampleBuffer array to become a length 32 array containing 32 arrays each with 3 random numbers.

If you are hoping for an array of 32 inner arrays, where the inner arrays each contain three random numbers, and where the inner arrays differ from each other, this will do it:

```auto
let sampleBuffer=[];
let bandsEnergy=[];

function setup() {

}

function draw() {
      for(let i=0; i<3; i++) {
        bandsEnergy[i] = random(10);
      }
      sampleBuffer.push(bandsEnergy.slice(0, 3));
      if(sampleBuffer.length==32) {
        noLoop();
        console.log(sampleBuffer);
      }
  }

```

After testing this, you can remove the call to the `noLoop` function.

But perhaps we are mistaken regarding what you are trying to do. If so, please clarify it for us

_EDIT (August 5, 2021):_

Perhaps the following example can help:

```auto
let sampleBuffer=[];
let bandsEnergy=[];

function setup() {
  createCanvas(400, 500);
  for (let i=0; i<20; i++) {
    for (let j=0; j<3; j++) {
      bandsEnergy[j] = random(10);
    }
    sampleBuffer.push(bandsEnergy.slice(0, 3));
  }
  frameRate(10);
}

function draw() {
  background(255);
  for (let j=0; j<3; j++) {
    bandsEnergy[j] = random(10);
  }
  for (let i=0; i<sampleBuffer.length; i++) {
    text(sampleBuffer[i], 10, i * 20 + 20);
  }
  sampleBuffer.push(bandsEnergy.slice(0, 3));
  sampleBuffer.splice(0,1);
 }

```

Image capture:  
 ![array_display](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/0/0279ff9ffc0fd42479698d15fcfff634d01bfac7.png)

Please let us know how it works out.

---

<div class="post-metadata">

**Author:** ![atagger](https://avatars.discourse-cdn.com/v4/letter/a/d6d6ee/32.png) [@atagger](https://discourse.processing.org/u/atagger)\
**Post date:** [August 5, 2021, 4:33pm UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/6 "2021-08-05T16:33:58Z")

</div>

The loop is running every frame of draw. So it runs three times, but forever. That’s what’s the splice does - it removes old values from the buffer, so there are only 32 values in there.

---

<div class="post-metadata">

**Author:** ![atagger](https://avatars.discourse-cdn.com/v4/letter/a/d6d6ee/32.png) [@atagger](https://discourse.processing.org/u/atagger)\
**Post date:** [August 5, 2021, 4:53pm UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/7 "2021-08-05T16:53:07Z")

</div>

Let me clarify. This is for a beat detection algorithm, and something that we are studying in school. I haven’t put the whole code here because it will get confusing, and it’s wrong.

The reason for the splice is so the array gets to a certain size, and then removes the first element in the array and pushes the newest element to the end, so it stays at a constant size once populated. It needs to run at 60 frames also. I’d like to avoid splicing / slicing arrays. The sampleBuffer should just accept an array into it (imagine you are storing values of 32 bands of an eq over time that all need to be averaged later). What I’m not understanding is why the values are getting replicating and why the other example with an object works (var b = { band: bandsEnergy }).

I guess I could ask this more generally. In draw, I want to make a loop that creates an array of values (each set in the array is different). This array is then pushed into another history array that is removing the first element so it stays at a constant size of desired length over time.

You would get something like this:

sampleBuffer[0] = [val1, val2, val3]  
…  
…  
sampleBuffer[31] = [val1, val2, val3]

where all the “vals” are the numbers generated in the initial loop (in this case it’s just random).

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [August 5, 2021, 6:53pm UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/8 "2021-08-05T18:53:19Z")

</div>

The following information on `Array`s may be useful:

> **[Array - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)**
>
> The JavaScript Array class is a global object that is used in the construction of arrays; which are high-level, list-like objects.

Consider whether these particular methods would help:

- [Array.prototype.pop()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop)
- [Array.prototype.push()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push)
- [Array.prototype.unshift()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift)

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [August 5, 2021, 8:34pm UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/9 "2021-08-05T20:34:14Z")

</div>

> [@atagger](#):
>
> I haven’t put the whole code here because it will get confusing, and it’s wrong.

Nevertheless, posting your code may help us understand what you are trying to do.

The example below initializes `sampleBuffer` with 32 inner `Arrays` of 3 random numbers each within the `setup()` function. The inner `Array`s are not replicated.

Within `draw()`, it pushes an `Array` of 3 new random numbers onto the top of `sampleBuffer` and removes the oldest `Array` of 3 numbers from the beginning of `sampleBuffer` during each frame. It also calls a `processTheData` function during each frame. As written here, that function displays the contents of `sampleBuffer`. Run the code, and notice the changes in the data during each frame. You can call `frameRate` to slow it down temporarily, if necessary.

```auto
let sampleBuffer=[];
let bandsEnergy=[];

function setup() {
  createCanvas(400, 660);
  // initialize sampleBuffer
  for (let i=0; i<32; i++) {
    sampleBuffer.push([random(10), random(10), random(10)]);
  }
}

function draw() {
  background(239);
  processTheData(sampleBuffer);
  // push new data on sampleBuffer
  sampleBuffer.push([random(10), random(10), random(10)]);
  // remove data at index 0 of sampleBuffer
  sampleBuffer.shift();
 }
 
 function processTheData(data) {
  for (let i=0; i<data.length; i++) {
    text(data[i], 10, i * 20 + 20);
  }
 }

```

> [@atagger](#):
>
> … 32 bands of an eq over time that all need to be averaged later …

You can rewrite the `processData` function to do this.

> [@atagger](#):
>
> What I’m not understanding is why the values are getting replicating …

That is because you populated `sampleBuffer` with 32 references to `bandsEnergy`.

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [August 5, 2021, 9:28pm UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/10 "2021-08-05T21:28:43Z")

</div>

We should take a moment here and make sure @atagger understands the concept of a reference. When you create an array and assign values to it as you do with `bandsEnergy`, when you use that array, passing it to a function, or adding it to another array/data structure, you are adding a reference to the original array. That means that if you change the array later, those changes will be reflected in all the places that reference the original array.

The `slice()` function is a common way to make a quick copy of an array. The original will not be modified, and the array returned by `slice()` will be a brand new array that contains the same values (note: don’t confuse **slice** with **splice** , they are very different). So specifically in the context of your code:

```auto
// this will add a reference to bandsEnergy, and if you change bandsEnergy later
// those changes will be reflected by each reference to that one array, which is
// why you would end up with an array of 32 identical arrays containing just the
// latest value
sampleBuffer.push(bandsEnergy);

// This, on the other hand, will make a copy of bandsEnergy and should achieve
// your desired behavior
sampleBuffer.push(bandsEnergy.slice());
// Note that slice takes two parameters, a start index and a length, and returns
// just that range of the array. However both of these parameters are optional.

```

There are other ways to solve this issue:

1. The spread operator

```auto
// The array initialize with the spread operator:
sampleBuffer.push([...bandsEnergy]);

```

1. Make bandsEnergy a local variable and initialize it to a new array `bandsEnergy = []` in each call to draw.

---

<div class="post-metadata">

**Author:** ![atagger](https://avatars.discourse-cdn.com/v4/letter/a/d6d6ee/32.png) [@atagger](https://discourse.processing.org/u/atagger)\
**Post date:** [August 5, 2021, 10:46pm UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/11 "2021-08-05T22:46:04Z")

</div>

Thank you. This is brilliant and what I was trying to understand. I never encountered this problem or limitation before, and did not understand it was passed as a reference. The three solutions you provided work. I had tried the spread operator but only like this: sampleBuffer.push(…bandsEnergy); which does not work, it needs the brackets.

The best solution is just redeclaring the bassEnergy[] every time on draw, it does exactly what I want it to do. And thank you also javagar! The frame rate tip was something I totally forgot about to be able to read stuff in the console.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [August 6, 2021, 12:29am UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/12 "2021-08-06T00:29:50Z")

</div>

This is my take on using **shift()** + **push()** as a queue of Float32Array which should be slightly faster: 🏎

> **[Array.prototype.shift() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift)**
>
> The shift() method removes the first
> element from an array and returns that removed element. This method changes the length
> of the array.

> **[Array.prototype.push() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push)**
>
> The push() method adds one or more elements to the end of
> an array and returns the new length of the array.

> **[Float32Array - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array)**
>
> The Float32Array typed array represents an array of 32-bit floating point numbers (corresponding to the C float data type) in the platform byte order. If control over byte order is needed, use DataView instead. The contents are initialized to 0. Once...

```auto
/**
 * Shift-Push 2D Queue (v1.0.0)
 * GoToLoop (2021-Aug-05)
 *
 * https://Discourse.Processing.org/t/
 * help-push-an-array-into-array-simple-question/31577/12
 */

'use strict';

const MAX_SAMPLES = 32, ENERGIES = 3, MAX_VAL = 10, sampleBuffer = [];

function setup() {
  createCanvas(400, 300).mousePressed(redraw);
  noLoop();
}

function draw() {
  background('#' + hex(~~random(0x1000), 3));

  const bandsEnergy = sampleBuffer.length >= MAX_SAMPLES &&
                      sampleBuffer.shift() || new Float32Array(ENERGIES);

  sampleBuffer.push(randomFill(bandsEnergy));

  console.table(sampleBuffer);
}

function randomFill(arr, maxVal = MAX_VAL) {
  for (var i = 0; i < arr.length; arr[i++] = random(maxVal));
  return arr;
}

```

---

<div class="post-metadata">

**Author:** ![atagger](https://avatars.discourse-cdn.com/v4/letter/a/d6d6ee/32.png) [@atagger](https://discourse.processing.org/u/atagger)\
**Post date:** [August 6, 2021, 12:34am UTC](https://discourse.processing.org/t/help-push-an-array-into-array-simple-question/31577/13 "2021-08-06T00:34:10Z")

</div>

You guys are awesome. This is what I was making ( the full code that the above problem was a snippet from ). I am having problems with this algorithm in the below code. Specifically the guy in the article uses 250 as his constant C (See beat algorithm 2 - frequency selected sound energy), no idea how he got that number, but it doesn’t work at all for me. See what you think, maybe this belongs in another post all together, but thought I’d share.

[GameDev Beat Detection](http://archive.gamedev.net/archive/reference/programming/features/beatdetection/)

```auto
let sound;
let size;

function preload() {

//put your sound file here
sound = loadSound("../audio/17.mp3");

}

function setup() {

  createCanvas(500,500);
  frameRate(60);
  beatDetect = new BeatDetect();
  sound.loop();

}

function draw() {

  background(0);

  if( beatDetect.detectBeat() ) {
    fill(255,0,0);
    //console.log(size);
    ellipse(width/2,height/2,size,size);
  }

}

//BeatDetect constructor
function BeatDetect() {

  //http://archive.gamedev.net/archive/reference/programming/features/beatdetection/

  let sampleBuffer=[]; //sample history buffer
  let bandsAverage=[]; //array of averages of the bands
  let energyBuffer=[]; //array of current sound energies per band

  let fourier = new p5.FFT();

  this.detectBeat = function() {

    //analyze fourier
    let spectrum=fourier.analyze();

      var count=0; // reset count every frame
      var isBeat=false; // reset isBeat every frame

      let bandsEnergy=[]; // start a new array each frame, so we don't pass in an array reference :)
      let bands_temp=[]; // temp array to split the frequency bands

      for(let i=0; i < spectrum.length; i++) {

        energyBuffer[i] = spectrum[i] * spectrum[i];
        bands_temp.push(energyBuffer[i]); // temp array to split into grouped bands

        //collect 32 samples (one band of 1024 i.e. 1024/32 = 32 bands)
        if(bands_temp.length == 32) {

           let sum=0; // init the sum to zero
           for(let j=0; j < bands_temp.length; j++) {
             sum+=bands_temp[j]; // get the sum of the band's samples
             bandsEnergy[count] = sum; // get average energy of band's grouping
           }

           bands_temp=[]; //clear temp bands_sum array for next set of 32 samples;
           count++; //increment count index, reset this every frame;

         }

      }

      sampleBuffer.push(bandsEnergy);

      //+1 since we remove a value each frame
      if(sampleBuffer.length == 43 + (1)) {

        for(let j = 0; j < bandsEnergy.length; j++) {

          let bandSum=0; // reset bandSum when we get to a new band

          //loop through all arrays in history buffer
          for(let k=0; k < sampleBuffer.length; k++) {
            bandSum += sampleBuffer[k][j]; // get the sum for each freq. band in the buffer
          }
          //calc avg from sum in each band of the buffer
          bandsAverage[j] = bandSum/sampleBuffer.length;
          }

        //remove the oldest sample from the array
        sampleBuffer.splice(0,1);

      }

      for(let k=0; k < sampleBuffer.length; k++) {

         let c = 1; //???

         if(bandsEnergy[k] > bandsAverage[k]*c) {
           isBeat=true;
           size=(bandsEnergy[k])*.0002;
           return isBeat;
         }
       }

       //console.log(bandsEnergy.length);
       //console.log(sampleBuffer.length);

      //console.log( bandsAverage[14] + "bandAverage");
      //console.log( bandsEnergy[14] + "bandEnergy");

    } // end DETECT

  } // end CONSTRUCTOR

```
