Converting a text file into a multidimensional array of data points

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