reshape method

void reshape(
  1. List<int> shape
)

Reshapes the array to shape.

Note: If you want the number of elements in the new shape to be the same as the number of elements in the original array, then you can use -1 as a placeholder for the number of elements in the new shape.

For example, if you have a 2x2 array, then you can reshape it to a 2x3 array by doing:

reshape([-1, 3]);

Warning: If the number of elements in the new shape is less than the number of elements in the original array, then the extra elements will be lost.

If the number of elements in the new shape is greater than the number of elements in the original array, then the extra elements will be filled with null.

Throws an ArgumentError if the length of shape does not match the number of dimensions in the array.

Throws an ArgumentError if shape contains any negative integers other than -1 or if it contains 0.

Implementation

void reshape(List<int> shape) {
  // Check that shape has the same number of dimensions as the array.
  if (shape.length != numDimensions) {
    throw ArgumentError('shape must have the same number of dimensions as '
        'the original array\n'
        'Expected: $numDimensions\n'
        'Actual: ${shape.length}');
  }

  // Check that shape only contains positive integers.
  for (int element in shape) {
    if (element < 1 && element != -1) {
      throw ArgumentError('shape must only contain positive integers\n'
          'Actual: $shape');
    }
  }

  /// The shape of the array before reshaping.
  final List<int> currentShape = ListTools.getShape(_data);

  // Replace -1 with the correct value.
  for (int i = 0; i < shape.length; i++) {
    if (shape[i] == -1) {
      shape[i] = currentShape[i];
    }
  }

  // If the shape is the same, then do nothing.
  if (const DeepCollectionEquality().equals(currentShape, shape)) return;

  // Go through each dimension and add or remove elements as needed.
  for (int i = 0; i < shape.length; i++) {
    // If the shape is the same, then do nothing.
    if (shape[i] == currentShape[i]) continue;

    /// The chunks of the array at the current dimension.
    late List<NdArray> chunks;
    try {
      chunks = extractDimension(i);
    } catch (e) {
      chunks = [this];
    }

    /// The desired length of the current chunks.
    final int desiredLength = shape[i];

    for (NdArray chunk in chunks) {
      // The actual length of the current chunk.
      int actualLength = chunk.shape.first;

      if (actualLength < desiredLength) {
        // Grow the chunk.
        while (actualLength < desiredLength) {
          // Build the injection.
          dynamic injection;
          for (int k = 0; k < numDimensions - (i + 1); k++) {
            injection = [injection];
          }

          if (injection == null) {
            chunk._data.add(null);
          } else {
            chunk._data.add(List<dynamic>.from(injection, growable: true));
          }

          actualLength++;
        }
      } else {
        // Shrink the chunk.
        chunk._data.length = desiredLength;
      }
    }
  }
}