about summary refs log tree commit diff stats
path: root/js/reshape.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/reshape.js')
-rw-r--r--js/reshape.js34
1 files changed, 34 insertions, 0 deletions
diff --git a/js/reshape.js b/js/reshape.js
new file mode 100644
index 0000000..f45b76f
--- /dev/null
+++ b/js/reshape.js
@@ -0,0 +1,34 @@
+// more details, <https://eli.li/reshape-in-javascript-and-apl>
+
+function ravel(array) {
+  if (!Array.isArray(array)) return [array];
+  return array.flatMap(val => ravel(val));
+}
+
+function reshape(shape, array) {
+  const totalSize = shape.reduce((acc, val) => acc * val, 1);
+  const ravelledArray = ravel(array);
+  const filledArray = Array.from({ length: totalSize }, (_, i) => ravelledArray[i % ravelledArray.length]);
+
+  // This function builds a nested array based on the given shape and data.
+  // It recursively constructs the nested array by slicing the data array and creating subarrays.
+  // The offset parameter is used to keep track of the current position in the data array.
+  function buildNestedArray(shape, data, offset = 0) {
+    // If the shape has only one element, return a slice of the data array with the specified size.
+    if (shape.length === 1) {
+      return data.slice(offset, offset + shape[0]);
+    }
+
+    // Extract the first element of the shape array as the size of the current dimension.
+    // The remaining elements form the subshape.
+    const [size, ...subShape] = shape;
+
+    // Calculate the size of the subarray for the next dimension.
+    const subArraySize = subShape.reduce((acc, val) => acc * val, 1);
+
+    // Create an array of size 'size' and recursively call buildNestedArray for each element.
+    return Array.from({ length: size }, (_, i) => buildNestedArray(subShape, data, offset + i * subArraySize));
+  }
+
+  return buildNestedArray(shape, filledArray);
+}