Converting a text file into a multidimensional array of data points

I want to be able to convert the following array from a text file

[[-7.5,-7.5,-5.0], [-2.5,-7.5,0.0], [2.5,-7.5,0.0], [7.5,-7.5,-5.0]], ,
[[-7.5,-2.5,-7.5], [-2.5,-2.5,5.0], [2.5,-2.5,5.0], [7.5,-2.5,-7.5]], ,
[[-7.5, 2.5, 0.0], [-2.5,2.5,-5.0], [2.5,2.5,-5.0], [7.5, 2.5, 0.0]], ,
[[-7.5, 7.5,-5.0], [-2.5,7.5,-10.00], [2.5,7.5,-10.00], [7.5,7.5,-5.0]]

into an array that can be used in p5 via createFileInput. Currently, I have split the array into the respective rows using the code below via double commas, but I’m not sure how to add the rows to a new multidimensional array as numbers instead of as a string.

function loadFile(file){
  array = file.data;
  splitStrings = split(array,', ,'); 
}

The three numbers can be seen as PVector.

So you have lines and each line has 4 PVectors

So you can make a 2D grid of PVector

You need to use split() command several times:

  • One you did already

  • Next at "]," (remove [ )

  • Next at , to fill the PVector

You can see the list as a list of quads / rectangles in 3D

Chrisir

Hello @TheSynchronomicon,

Reference:
https://p5js.org/reference/#/p5/float

Some hints here that may help:

You can look up the references.

Once I can work with the data I then proceed to the next step.
I leave the multidimensional array with you.

:)

That’s not even a 2d array, but a 3d 1 w/ dimensions 4x4x3:

const DATA3D_4x4x3 = `
[[-7.5,-7.5,-5.0], [-2.5,-7.5,0.0], [2.5,-7.5,0.0], [7.5,-7.5,-5.0]], ,
[[-7.5,-2.5,-7.5], [-2.5,-2.5,5.0], [2.5,-2.5,5.0], [7.5,-2.5,-7.5]], ,
[[-7.5, 2.5, 0.0], [-2.5,2.5,-5.0], [2.5,2.5,-5.0], [7.5, 2.5, 0.0]], ,
[[-7.5, 7.5,-5.0], [-2.5,7.5,-10.00], [2.5,7.5,-10.00], [7.5,7.5,-5.0]]
`;

Indeed that’s the 1st step. But there’s a lot more to do in order to convert it to a 3d array!

After that 1st split() we only have a 1d array of strings so far:
const strArr1d = data.split(', ,');

As for the 2nd step we can create a 2d array of strings by looping & splitting that 1d array of strings w/ delimiter "],":

const delim = '],', len = strArr1d.length, strArr2d = Array(len).fill();
for (var i = 0; i < len; ++i)  strArr2d[i] = strArr1d[i].split(delim);

Alternatively we can use Array.from() to do the same in 1 line:

const delim = '],', strArr2d = Array.from(strArr1d, str => str.split(delim));

Now that we have a 2d array of strings we need to upgrade it to a 3d array of floats.

That’s the most complicated part b/c we need to turn each string of the children arrays into an array of floats and assign it back to the them.

That way we’re adding a 3rd dimension to the 2d array, effectively converting it to a 3d array.

For that I’ve created a separate function named create3dArrFrom2d():

function create3dArrFrom2d(arr2d) {
  const regexp = /[\[\]]/g, empty = '', delim = ',';

  const mapFn = str => new Float64Array(
    str.replace(regexp, empty).split(delim)
  );

  arr2d.forEach((arr1d, idx) => arr2d[idx] = arr1d.map(mapFn));

  return arr2d;
}

The function uses method String::replace() together w/ the regex /[\[\]]/g in order to remove each [ & ] leftover characters from each string before we split() it:

In addition to that it iterates the outer array via method Array::forEach():

And then each inner array is transformed into a 2d array via Array::map()'s callback:

And finally inside that callback we have Float64Array which converts the newly split() string array into a typed array of float values:

Here’s the full code which can be copied & pasted into the browser’s console b/c it’s just vanilla JS:

sketch.js:

/**
 * Array3D Split Parse (v1.0.0)
 * GoToLoop (2022/Mar/30)
 *
 * https://Discourse.Processing.org/t/
 * converting-a-text-file-into-a-multidimensional-array-of-data-points/36007/4
 */

'use strict';

var FILENAME = 'data3d_4x4x3.txt', DATA3D_4x4x3 = `
[[-7.5,-7.5,-5.0], [-2.5,-7.5,0.0], [2.5,-7.5,0.0], [7.5,-7.5,-5.0]], ,
[[-7.5,-2.5,-7.5], [-2.5,-2.5,5.0], [2.5,-2.5,5.0], [7.5,-2.5,-7.5]], ,
[[-7.5, 2.5, 0.0], [-2.5,2.5,-5.0], [2.5,2.5,-5.0], [7.5, 2.5, 0.0]], ,
[[-7.5, 7.5,-5.0], [-2.5,7.5,-10.00], [2.5,7.5,-10.00], [7.5,7.5,-5.0]]
`;

var floatArr3d;

console.log(DATA3D_4x4x3);
handleFile({ name: FILENAME, data: DATA3D_4x4x3 });
console.table(floatArr3d);

function handleFile(file) {
  const { data, name } = file;
  if (typeof data != 'string')  return console.error('Invalid file:', name);

  const strArr1d = data.split(', ,');
  console.table(strArr1d);

  const delim = '],', strArr2d = Array.from(strArr1d, str => str.split(delim));
  console.table(strArr2d);

  floatArr3d = create3dArrFrom2d(strArr2d);
}

function create3dArrFrom2d(arr2d) {
  const regexp = /[\[\]]/g, empty = '', delim = ',';

  const mapFn = str => new Float64Array(
    str.replace(regexp, empty).split(delim)
  );

  arr2d.forEach((arr1d, idx) => arr2d[idx] = arr1d.map(mapFn));

  return arr2d; // it's a 3d array now
}

You can use the following code to run it inside a browser:

index.html:

<script async src=sketch.js></script>

And also batch files for both Node & Deno:

node-run-sketch.bat:

node sketch.js
pause

deno-run-sketch.bat

deno run sketch.js
pause
2 Likes

If you are at the origin of the file, it’s simpler to redact it as a JSON standard :

let s =
[ [[-7.5,-7.5,-5.0], [-2.5,-7.5,0.0], [2.5,-7.5,0.0], [7.5,-7.5,-5.0]], [[-7.5,-2.5,-7.5], [-2.5,-2.5,5.0], [2.5,-2.5,5.0], [7.5,-2.5,-7.5]], [[-7.5, 2.5, 0.0], [-2.5,2.5,-5.0], [2.5,2.5,-5.0], [7.5, 2.5, 0.0]], [[-7.5, 7.5,-5.0], [-2.5,7.5,-10.00], [2.5,7.5,-10.00], [7.5,7.5,-5.0]] ]

( just add a surrounding pair of brackets)
You just have to read it with parse, and that’s all.

let big = JSON.parse(s)
// access
console.log(big). // array(4) most external
console.log(big[0]) // array(4) a line
console.log(big[0][0]) // array(3) one vector
console.log(big[0][0][0]) // an element -7.5.

HTH

2 Likes