Skip to content
Open
170 changes: 170 additions & 0 deletions lib/node_modules/@stdlib/ndarray/splice/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<!--

@license Apache-2.0

Copyright (c) 2026 The Stdlib Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->

# splice

> Return an [`ndarray`][@stdlib/ndarray/ctor] where elements of an input [`ndarray`][@stdlib/ndarray/ctor] are replaced or removed along a specific dimension.

<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->

<section class="intro">

</section>

<!-- /.intro -->

<!-- Package usage documentation. -->

<section class="usage">

## Usage

```javascript
var splice = require( '@stdlib/ndarray/splice' );
```

#### splice( x, slices\[, values\[, options]] )

Returns an [`ndarray`][@stdlib/ndarray/ctor] where elements of an input [`ndarray`][@stdlib/ndarray/ctor] are replaced or removed along a specific dimension.

```javascript
var Slice = require( '@stdlib/slice/ctor' );
var array = require( '@stdlib/ndarray/array' );

var x = array( [ [ 1.0, 2.0 ], [ 3.0, 4.0 ], [ 5.0, 6.0 ] ] );
// returns <ndarray>[ [ 1.0, 2.0 ], [ 3.0, 4.0 ], [ 5.0, 6.0 ] ]

var y = array( [ [ 20.0 ], [ 40.0 ], [ 60.0 ] ] );
// returns <ndarray>[ [ 20.0 ], [ 40.0 ], [ 60.0 ] ]

var s = new Slice( 1, null, 1 );
// returns <Slice>

var out = splice( x, s, y );
// returns <ndarray>[ [ 1.0, 20.0 ], [ 3.0, 40.0 ], [ 5.0, 60.0 ] ]
```

The function accepts the following arguments:

- **x**: input [`ndarray`][@stdlib/ndarray/ctor].
- **slices**: a [`Slice`][@stdlib/slice/ctor] instance, `null`, `undefined`, an integer, or an array of such values. If provided `null` or `undefined`, the argument is equivalent to `new Slice()` (i.e., the returned view should include all elements along a specified dimension). If provided an integer less than zero, the corresponding element along the specified dimension is resolved relative to the last element along that dimension. For negative integers, the last element corresponds to the value `-1`.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **slices**: a [`Slice`][@stdlib/slice/ctor] instance, `null`, `undefined`, an integer, or an array of such values. If provided `null` or `undefined`, the argument is equivalent to `new Slice()` (i.e., the returned view should include all elements along a specified dimension). If provided an integer less than zero, the corresponding element along the specified dimension is resolved relative to the last element along that dimension. For negative integers, the last element corresponds to the value `-1`.
- **slices**: a [`Slice`][@stdlib/slice/ctor] instance, `null`, `undefined`, an integer, or an array of such values. If provided `null` or `undefined`, the argument is equivalent to `new Slice()` (i.e., the returned view should include all elements along a specified dimension). If provided a negative integer, the index at which to splice is determined by counting backward from the last element along that dimension (where `-1` refers to the last element).

Adapted from https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/ext/index-of.

- **values**: an [`ndarray`][@stdlib/ndarray/ctor] or an array of [`ndarrays`][@stdlib/ndarray/ctor] containing the elements to insert. The provided [`ndarrays`][@stdlib/ndarray/ctor] must be [broadcast compatible][@stdlib/ndarray/base/broadcast-shapes] with the slice region (_optional_).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be more explicit in terms of what we mean by being broadcast compatible with the slice region. I believe we mean to say that each ndarray must be broadcast compatible with the shape of the input ndarray except for the dimension defined by options.dim. I believe we have similar language elsewhere. E.g., in ndarray/concat.

Furthermore, similar to concat, you need to describe the data type of the output ndarray and the memory layout of the output ndarray. In contrast to concat, that can likely be described in a Notes section below.

Copy link
Copy Markdown
Member

@kgryte kgryte Jun 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably also state somewhere that each ndarray must have the same or fewer dimensions than the input ndarray. Right now, you don't validate this, but I think this is a bug, as concat will simply promote everything to a common shape. That is odd behavior for splice, as it means that I can have a 3D input ndarray and then try to splice in a 4D or 5D array, which doesn't make sense. In the real world, that would be like trying to squeeze a nail multiple times bigger into a hole designed for a needle. If a user wants that sort of behavior, they can first broadcast the input ndarray to the desired dimensionality before calling splice.

So, in short, you need to be validating that the number of dimensions in each values ndarray does not exceed the dimensions of the input ndarray.

- **options**: function options (_optional_).

The function accepts the following `options`:

- **dim**: dimension along which to perform the operation. The index is resolved relative to the last dimension, with the last dimension corresponding to the value `-1`. Default: `-1`.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **dim**: dimension along which to perform the operation. The index is resolved relative to the last dimension, with the last dimension corresponding to the value `-1`. Default: `-1`.
- **dim**: dimension along which to perform the operation. If provided a negative integer, the dimension along which to perform the operation is determined by counting backward from the last dimension (where `-1` refers to the last dimension). Default: `-1`.

Use language consistent with other packages. This is a common review comment.

Copy link
Copy Markdown
Member

@kgryte kgryte Jun 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I don't believe we need to restrict dim to be a negative integer, as in concat, as splice does not have the same constraints as concat. Instead, what does need to be done, since opts.dim, is passed to concat is that the provided dim option needs to be normalized internally to a negative dimension index before calling into concat. You seem to assume in all your examples that dim is negative. That is an incorrect assumption.


By default, the function performs the operation on the last dimension. To perform the operation on any other dimension, specify the `dim` option.

```javascript
var Slice = require( '@stdlib/slice/ctor' );
var array = require( '@stdlib/ndarray/array' );

var x = array( [ [ 1.0, 2.0 ], [ 3.0, 4.0 ], [ 5.0, 6.0 ] ] );
// returns <ndarray>[ [ 1.0, 2.0 ], [ 3.0, 4.0 ], [ 5.0, 6.0 ] ]

var y = array( [ [ 10.0, 20.0 ] ] );
// returns <ndarray>[ [ 10.0, 20.0 ] ]

var s = new Slice( 1, 2, 1 );
// returns <Slice>

var out = splice( x, s, y, {
'dim': -2
});
// returns <ndarray>[ [ 1.0, 2.0 ], [ 10.0, 20.0 ], [ 5.0, 6.0 ] ]
```

Copy link
Copy Markdown
Member

@kgryte kgryte Jun 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this documentation, you have omitted examples showing the various call signatures which may be of interest. For example, in none of the examples do you show how you can perform multiple splices (including multiple removals, multiple insertions, etc). Nor do you show an example using broadcasting. Nor do you show how you can use splice to only remove elements. Nor do you show how you can use splice to insert without removal to expand an ndarray.

If all I knew was what the docs currently show, I would have little idea of the full capabilities of this API. I suggest thinking more from the reader's point of view and providing more examples showcasing all the things this API can do. This API is quite powerful, and your current docs fail to capture that.

</section>

<!-- /.usage -->

<!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->

<section class="notes">

</section>

<!-- /.notes -->

<!-- Package usage examples. -->

<section class="examples">

## Examples

```javascript
var uniform = require( '@stdlib/random/uniform' );
var ndarray2array = require( '@stdlib/ndarray/to-array' );
var Slice = require( '@stdlib/slice/ctor' );
var splice = require( '@stdlib/ndarray/splice' );

var x = uniform( [ 3, 3, 3 ], -10, 10 );
console.log( ndarray2array( x ) );

var s = new Slice( 1, 2, 1 );

var y = uniform( [ 1, 3, 3 ], 20, 40 );
console.log( 'Values: ', ndarray2array( y ) );

var out = splice( x, s, y, {
'dim': -3
});
console.log( ndarray2array( out ) );
```

</section>

<!-- /.examples -->

<!-- Section to include cited references. If references are included, add a horizontal rule *before* the section. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->

<section class="references">

</section>

<!-- /.references -->

<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->

<section class="related">

</section>

<!-- /.related -->

<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->

<section class="links">

[@stdlib/slice/ctor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/slice/ctor

[@stdlib/ndarray/ctor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/ctor

[@stdlib/ndarray/base/broadcast-shapes]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/base/broadcast-shapes

<!-- <related-links> -->

<!-- </related-links> -->

</section>

<!-- /.links -->
Loading