 # Moving elements within a 2d array

I previously built a midi to control voltage converter and used an array to keep track of which keys were being pressed and in which order. When a note is released, it's corresponding element is changed to zero and then I used a subroutine to reorganize the array so the zeros are at the end.

``````unsigned int pitchVoltage = {0};

for (int i = 0; i < 6; i++) {
if (pitchVoltage[i] == voltage) {
pitchVoltage[i] = 0;
removeZeros(pitchVoltage, sizeof(pitchVoltage) / sizeof(pitchVoltage));
}
}

void removeZeros(int array[], size_t length) {
if (array != nullptr && length > 0) {
for (size_t i = 0; i < length; i++) {
if (array[i] == 0) {
for (size_t j = i + 1; j < length; j++) {
if (array[j] != 0) {
array[i] = array[j];
array[j] = 0;
break;
}
}
}
}
}
}

``````

this works, but admittedly I found the "remove zeros" subroutine online and only have a superficial understanding of what is happening.

Currently, Im adapting my single channel midi to cv device to be a two channel one and have changed the single line array into a 2d one to keep track of which notes are being held on each of the two respective midi channels. Ive (attempted to) modify the "remove zeros" subroutine to accommodation the two levels of the array like so:

``````unsigned int pitchVoltage {0};

for (int i = 0; i < 6; i++) {
if (pitchVoltage[x][i] == voltage) {
pitchVoltage[x][i] = 0;
removeZeros( pitchVoltage[x], sizeof(pitchVoltage[x]) / sizeof(pitchVoltage[x]));
}
}

void removeZeros(int array[], size_t length) {
if (array != nullptr && length > 0) {
for (size_t i = 0; i < length; i++) {
if (array[i] == 0) {
for (size_t j = i + 1; j < length; j++) {
if (array[j] != 0) {
array[i] = array[j];
array[j] = 0;
break;
}
}
}
}
}
}

``````

this seems to be working, but only for the first level of the array, when x=0. When x=1, it does not work.

Any ideas of what is the issue, or how to solve it, or even a better way of how to do this whole process?

Thanks

can you provide some test data: the values initially in the array and the final array values?

sure.

so lets say I press 4 keys subsequently. the array records the cooresponding DAC write values in the order that they were pressed:

notecount=4
pitchVoltage = {200,300,100, 500,0, 0} (for example... not real values)

If I release the 2nd pressed key, that value becomes a zero and the "remove zeros" routine changes it to:

notecount=3
pitchVoltage = {200,100, 500,0, 0, 0}

This is so that the order of the array keeps in line with my noteCount tally and allows the program to keep track of Last note priority. Does that make sense?

Sorry I dont currently have "real" data from a serial monitor. Im using a pro mini and the serial port is being used for the DIN midi.

I guess that I can try to get softSerial working for debugging, but Im not sure if I have any spare pins would this be a valid example

``````disp:   1   2   0   3   4   0   0   5   6
compress:
disp:   1   2   3   4   5   6   0   0   0

``````

here are results for a 2d array

``````disp:   1   2   0   3   4   0   0   5   6   0
disp:   9   0   0   8   7   0   6   5   4   3
compress:
compress:
disp:   1   2   3   4   5   6   0   0   0   0
disp:   9   8   7   6   5   4   3   0   0   0
``````

using this code

``````#include <stdio.h>

#define N_COL   10

int vec [][N_COL] = {
{ 1, 2, 0, 3,   4, 0, 0, 5,   6 },
{ 9, 0, 0, 8,   7, 0, 6, 5,   4, 3 },
};
#define N_ROW   sizeof(vec)/(N_COL*sizeof(int))

void
compress (
int    *vec,
int     size )
{
printf ("%s:\n", __func__);
unsigned i = 0;
for (unsigned n = 0; n < size; n++)
if (0 != vec [n]) {
vec [i] = vec [n];
if (i++ != n)
vec [n] = 0;
}
}

void
disp (
int    *vec,
int     size )
{
printf ("%s:", __func__);
for (unsigned n = 0; n < size; n++)
printf (" %3d", *vec++);
printf ("\n");
}

int
main ()
{
disp     (& vec , N_COL);
disp     (& vec , N_COL);

compress (& vec , N_COL);
compress (& vec , N_COL);

disp     (& vec , N_COL);
disp     (& vec , N_COL);

return 0;
}
``````

Cool! Thanks! Ill try it out tomorrow

For the record, my "removeZeros" compression routine works fine. The problem I was experiencing was from a typo in another part of the code (DUH!) It turns out that when I adapted the one channel version to the two channel version, I forgot to change one of my variables into an array: i had `CV`, when it should have been `CV[x]`. oof!
Im surprised that it wasnt causing deeper problems.

gcjr, thanks for taking the time to help me out. While i never need to use you routine, it was helpful. Just seeing another take on what was basically the same function helps (a bit) to understand the process that it performs.

best
Charlie