Skip to content

feat(array): add new array helpers and array-like detection#525

Open
nev21 wants to merge 1 commit intomainfrom
nev21/array
Open

feat(array): add new array helpers and array-like detection#525
nev21 wants to merge 1 commit intomainfrom
nev21/array

Conversation

@nev21
Copy link
Contributor

@nev21 nev21 commented Feb 26, 2026

  • add arrUnique, arrCompact, arrFlatten, arrGroupBy, arrChunk with ArrayLike support
  • add isArrayLike helper and export in index
  • add tests for new array helpers and isArrayLike

- add arrUnique, arrCompact, arrFlatten, arrGroupBy, arrChunk with ArrayLike support
- add isArrayLike helper and export in index
- add tests for new array helpers and isArrayLike
@nev21 nev21 added this to the 0.13.0 milestone Feb 26, 2026
@nev21 nev21 requested a review from a team as a code owner February 26, 2026 06:36
Copilot AI review requested due to automatic review settings February 26, 2026 06:36
@nev21 nev21 requested a review from a team as a code owner February 26, 2026 06:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds five new array helper functions with ArrayLike support and introduces the isArrayLike type guard helper. The changes enhance the library's array manipulation capabilities with common utility functions like deduplication, compaction, flattening, grouping, and chunking, all following the established arr* naming convention and supporting both arrays and array-like objects.

Changes:

  • Added isArrayLike helper function to detect array-like objects (objects with numeric length property >= 0)
  • Added five new array utility functions: arrUnique, arrCompact, arrFlatten, arrGroupBy, and arrChunk
  • Updated bundle size limits to accommodate the new functionality (~1KB increase)
  • Removed redundant /*#__PURE__*/ markers from simple function assignments in unwrapFunction.ts
  • Updated version documentation in customError.ts

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
lib/src/helpers/base.ts Adds isArrayLike type guard function with proper null/undefined/function checks and exports it
lib/src/array/unique.ts New function to remove duplicate values from arrays using object-based tracking
lib/src/array/compact.ts New function to filter out all falsy values from arrays
lib/src/array/flatten.ts New function to flatten nested arrays to specified depth
lib/src/array/groupBy.ts New function to group array elements by callback result
lib/src/array/chunk.ts New function to split arrays into fixed-size chunks
lib/src/index.ts Exports all new functions and types including isArrayLike
lib/test/src/common/helpers/base.test.ts Comprehensive tests for isArrayLike covering various input types
lib/test/src/common/helpers/array.test.ts Comprehensive tests for all five new array functions
lib/src/internal/unwrapFunction.ts Removes redundant /*#__PURE__*/ markers from simple assignments
lib/src/helpers/customError.ts Updates version comment from v0.12.7 to v0.13.0 for superArgsFn parameter
.size-limit.json Updates bundle size limits to reflect new functionality
lib/test/bundle-size-check.js Updates bundle size limits for ES5 and ES6 builds
README.md Updates documentation to include new array functions in the function list

* Licensed under the MIT license.
*/

import { isArrayLike, isUndefined } from "../helpers/base";
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

The isUndefined import is unused and should be removed to keep the code clean and reduce bundle size.

Suggested change
import { isArrayLike, isUndefined } from "../helpers/base";
import { isArrayLike } from "../helpers/base";

Copilot uses AI. Check for mistakes.
const seen: any = objCreate(null);

arrForEach(theArray, (item) => {
const key = normalizeJsName((typeof item) + "_" + item);
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

Using normalizeJsName for deduplication keys is problematic. The normalizeJsName function is designed to convert strings into valid JavaScript identifiers by replacing invalid characters with underscores, not for creating unique deduplication keys.

This implementation has potential issues:

  1. It's unnecessary overhead - the function performs regex replacement meant for identifier normalization
  2. It could theoretically cause key collisions if values contain characters that get normalized (e.g., spaces, dots, special chars)
  3. The approach works for primitives but would silently fail for objects (all objects would map to "object_[object Object]")

A simpler and more reliable approach would be to use the value directly as the key with type prefix, since JavaScript object keys are already strings:

const key = (typeof item) + ":" + item;

This avoids the normalization overhead and is clearer in intent. Alternatively, for ES6+ environments, consider using a Set or Map for better performance and correctness.

Copilot uses AI. Check for mistakes.
Comment on lines +57 to +63
const keyStr = asString(callbackFn.call(thisArg, item, idx, theArray));

if (!objHasOwn(result, keyStr)) {
result[keyStr] = [];
}

result[keyStr].push(item);
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

The callback return value is being converted to string using asString, but the function signature indicates it can return string | number | symbol. Converting symbols to strings defeats their purpose as unique identifiers and may cause unexpected behavior. Numbers are fine to convert to strings for object keys, but symbols should be handled differently.

Consider checking the type and handling symbols separately, or document that symbols will be converted to strings (which would make them lose their uniqueness property). The return type and implementation should be consistent.

Suggested change
const keyStr = asString(callbackFn.call(thisArg, item, idx, theArray));
if (!objHasOwn(result, keyStr)) {
result[keyStr] = [];
}
result[keyStr].push(item);
const rawKey = callbackFn.call(thisArg, item, idx, theArray);
const key: string | number | symbol = typeof rawKey === "symbol" ? rawKey : asString(rawKey);
if (!objHasOwn(result, key)) {
result[key] = [];
}
result[key].push(item);

Copilot uses AI. Check for mistakes.
Comment on lines +42 to +47
let chunkIdx = 0;

arrForEach(theArray, (item) => {
if (idx % size === 0) {
result.push([]);
chunkIdx = result.length - 1;
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

The variable chunkIdx is recalculated as result.length - 1 on every chunk creation, but it could be simplified. Since chunks are added sequentially, you could just increment chunkIdx or track it more efficiently. However, the current implementation is clear and the performance impact is negligible, so this is a very minor optimization opportunity rather than a bug.

Suggested change
let chunkIdx = 0;
arrForEach(theArray, (item) => {
if (idx % size === 0) {
result.push([]);
chunkIdx = result.length - 1;
let chunkIdx = -1;
arrForEach(theArray, (item) => {
if (idx % size === 0) {
result.push([]);
chunkIdx++;

Copilot uses AI. Check for mistakes.
* new Custom Error instance is being created.
* @param errorBase - [Optional] (since v0.9.6) The error class to extend for this class, defaults to Error.
* @param superArgsFn - [Optional] (since v0.12.7) An optional function that receives the constructor arguments and
* @param superArgsFn - [Optional] (since v0.13.0) An optional function that receives the constructor arguments and
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

The version number in the JSDoc comment for the superArgsFn parameter has been changed from v0.12.7 to v0.13.0. This change should be verified:

  • If the parameter was actually added in v0.12.7, this change is incorrect and breaks the documentation history
  • If the parameter is being added in this PR (v0.13.0), the change is correct
  • If the parameter existed but is being significantly modified in v0.13.0, that should be noted differently in the documentation

Please verify the git history to confirm whether this parameter existed in v0.12.7 or is being introduced in v0.13.0.

Suggested change
* @param superArgsFn - [Optional] (since v0.13.0) An optional function that receives the constructor arguments and
* @param superArgsFn - [Optional] (since v0.12.7) An optional function that receives the constructor arguments and

Copilot uses AI. Check for mistakes.
@nev21 nev21 modified the milestones: 0.13.0, 0.14.0 Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants