Linear array of values to grid

Say i have an array of 16 values eg {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25} but i want to display them in a 4 x 4 grid. What is the easiest way to get them into a 2d array that looks like this?

{
  {10,11,12,13},
  {14,15,16,17},
  {18,19,20,21},
  {22,23,24,25}
}

i’m sure i did this before but cannot remember how!

2 Likes

One way is to use a for inside another for :

int step = 4 ;
int myNewArrayLength = myArray.length / step ;
int[] myNewArray = [myNewArrayLength] ; 

for (int i = 0 ; i < myArray.length ; i += step){
    for (int y = i ; y < i + step ; y ++){
      myNewArray[i / step].push(y);
   }
}

But there is probably a better way, with proper Java methods …

1 Like

you don’t have to turn it into a 2d array array to display.

if you know the width and height you can

  for(int y = 0; y < height; y++) {
    for(int x = 0; x < width; x++) {
      int xy = x + y * width;
      fill(values[xy]);
      rect(x * rectSize, y * rectSize, rectSize, rectSize);
    }
  }

if you don’t know the width and height and want to keep the 1d array you can still present them in 2d with a few conditions

    //calculate the stride* 
    int stride = sqrt(arr.length);
    //calculate the x & y on the fly
    for (int i = 0; i < arr.length; i++) {
    //note you are doing mod and div operations for every index
    //ok if your array is small not if it isn't
    int x = floor(i % stride);
    int y = floor(i / stride);
  }

*assumes width and height are sqr. there is a way around this but it isn’t perfect.

here’s an example

int[] values;
int rectSize = 8;
boolean drawStyle;
void setup() {
  size(512, 512, P2D);
  noStroke();
  
  drawStyle = false;
  //instantiate the array
  values = new int[16];
  //fill the array with random values
  for(int i = 0; i < values.length; i++) {
    values[i] = (int)random(255);
  }
}

void keyPressed() {
  drawStyle = !drawStyle;
}

void draw() {
  background(255, 0, 255);  
  if(drawStyle) {
    draw1();
  }
  else {
    draw2();
  }
  fill(255);
  text(drawStyle ? "draw1" : "draw2", 0, height - 16);
}

void draw1() {
  //calculate the stride
  int stride = (int)sqrt(values.length);
  int x, y;
  //calculate each x and y and fill a point
  for(int i = 0; i < values.length; i++) {
    x = floor(i % stride);
    y = floor(i / stride);
    fill(values[i]);
    rect(x * rectSize, y * rectSize, rectSize, rectSize);
  }
}

void draw2() {
  int vWidth = 4;
  int vHeight = 4;
  for(int y = 0; y < vHeight; y++) {
    for(int x = 0; x < vWidth; x++) {
      int xy = x + y * vWidth;
      fill(values[xy]);
      rect(x * rectSize, y * rectSize, rectSize, rectSize);
    }
  }
}

after all that it’s probably best to decide the appropriate array format from the get go.

/**
 * IntArr1dTo2d (v1.0)
 * GoToLoop (2019/Jan/)
 * https://Discourse.Processing.org/t/linear-array-of-values-to-grid/14206/4
 */

static final int ROWS = 4, COLS = 4;

int[] arr = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
int [][] matrix;

void setup() {
  println(arr);
  println();

  matrix = intArr1dTo2d(ROWS, COLS, arr);

  int i = 0;
  for (int[] arr1d : matrix)  println("[" + i++ + "] " + join(str(arr1d), ','));

  exit();
}


@SafeVarargs static final int[][]
  intArr1dTo2d(final int rows, final int cols, final int... arr1d) {

  final int r = abs(rows), c = abs(cols), len = r * c;
  final int[][] arr2d = new int[r][c];

  int idx = 0, row = 0, col = 0;

  if (len != 0 & arr1d != null)  for (final int v : arr1d) {
    arr2d[row][col] = v;
    if ((col = (col + 1) % c) == 0)  if (++row == r)  break;
  }

  return arr2d;
}

This is an important point – this is also how Processsing implements images and the canvas (PImage / PGraphics). It does not reorganize the values into 2D – instead, it uses 2D access logic.

Pixel color values are saved in a 1D array, pixels. You can either access pixels[i], or you can use get(x, y) – which returns pixels[y*width + x] – or set(x, y, c) – which is equivalent to pixels[y*width+x] = c.

1 Like