Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/array/pullAt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,30 @@ describe('pullAt', () => {
expect(actual).toEqual([2, 4, 12, 8, 6, 10]);
});

it('should work with a single negative index', () => {
const array = [10, 20, 30, 40, 50];
const result = pullAt(array, [-1]);

expect(array).toEqual([10, 20, 30, 40]);
expect(result).toEqual([50]);
});

it('should work with multiple negative indices', () => {
const array = [10, 20, 30, 40, 50];
const result = pullAt(array, [-1, -2]);

expect(array).toEqual([10, 20, 30]);
expect(result).toEqual([50, 40]);
});
Comment on lines +61 to +67
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The new negative-index tests cover in-range negatives, but there’s still no coverage for out-of-range negatives (e.g. index < -array.length). Given at() returns undefined for those, it would be good to add a case asserting pullAt also returns undefined and does not remove any element for such indices.

Copilot uses AI. Check for mistakes.

it('should work with mixed positive and negative indices', () => {
const array = [10, 20, 30, 40, 50];
const result = pullAt(array, [0, -1]);

expect(array).toEqual([20, 30, 40]);
expect(result).toEqual([10, 50]);
});

it('should work with objects', () => {
const foo = { foo: 1 };
const bar = { foo: 2 };
Expand Down
4 changes: 3 additions & 1 deletion src/array/pullAt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import { at } from './at.ts';
*/
export function pullAt<T>(arr: T[], indicesToRemove: number[]): T[] {
const removed = at(arr, indicesToRemove);
const indices = new Set(indicesToRemove.slice().sort((x, y) => y - x));

const normalizedIndices = indicesToRemove.map(index => (index < 0 ? arr.length + index : index));
Comment on lines +21 to +22
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

normalizedIndices only adds arr.length for negative values, but doesn’t apply the same integer coercion / bounds handling as at(). This can cause pullAt to mutate the array for out-of-range negative indices (e.g. index < -arr.length becomes a negative normalized index and splice will remove from the end) even though at() returns undefined for those keys. Consider normalizing indices using the same rules as at() (truncate non-integers, add length for negatives) and then filtering out indices that are still out of [0, length) before splicing, so nonexistent indices don’t remove unrelated elements.

Suggested change
const normalizedIndices = indicesToRemove.map(index => (index < 0 ? arr.length + index : index));
const length = arr.length;
const normalizedIndices = indicesToRemove
.map((index) => {
let idx = Math.trunc(index);
if (idx < 0) idx += length;
return idx;
})
.filter((idx) => idx >= 0 && idx < length);

Copilot uses AI. Check for mistakes.
const indices = new Set(normalizedIndices.slice().sort((x, y) => y - x));

for (const index of indices) {
arr.splice(index, 1);
Expand Down
Loading