FIELD NOTE 003TypeScriptReviewed July 2026

Array Deduplication (Object/Array Support)

Supports deduplication of not only primitive types but also complex types like objects and arrays, using JSON.stringify to generate unique identifiers

Copy the complete example or adapt its typed interface to your project. Comments are kept inside the snippet so the intent travels with the code.

pattern.ts
/**
 * Array deduplication (supports primitive + reference types)
 * @param arr Array to be deduplicated
 * @returns New deduplicated array
 */
function uniqueArray<T>(arr: T[]): T[] {
  const cache = new Set<string>();
  return arr.filter(item => {
    const key = JSON.stringify(item);
    if (cache.has(key)) return false;
    cache.add(key);
    return true;
  });
}

// Usage Example
const arr = [1, 2, 2, { a: 1 }, { a: 1 }, [1], [1]];
console.log(uniqueArray(arr)); // [1, 2, { a: 1 }, [1]]

Great for deduplicating API response data, list data, or arrays containing objects/arrays

Implementation note

Review the input assumptions and browser or runtime support before adopting a utility unchanged. Small helpers are easiest to maintain when their contract stays narrow.

How it works

Each item is serialized to a JSON string that becomes a Map key. The first item producing a key is retained, allowing primitive values, arrays, and simple objects with the same serial form to collapse into one result.

What to watch for

JSON serialization is sensitive to property order and cannot represent functions, undefined members, symbols, BigInt, or circular structures. Different values can serialize alike, while semantically equal objects with different key order can remain separate.

Production use

Use the pattern for small, JSON-compatible collections whose equality rule is intentionally based on serialized structure. For domain entities, deduplicate by a stable identifier or provide a key selector that states the equality decision directly.

Before you ship

  • Confirm the input contract with tests that cover empty, invalid, boundary, and representative real-world values before sharing the helper across a codebase.
  • Keep the function focused on one responsibility and name any project-specific policy explicitly instead of hiding it inside a generic-looking utility.
  • Measure behavior in the browsers or runtime versions your product supports, especially when timing, storage, DOM state, locale, or network access is involved.
  • Document the return type, mutation behavior, failure mode, and performance characteristics beside the call site so future maintainers can evaluate changes safely.
  • Compare the example with current official platform documentation when it relies on a browser API, language feature, or runtime behavior that may change over time.
  • If the helper crosses a trust boundary, validate again on the server and avoid treating browser-side checks, TypeScript annotations, or formatted output as a security guarantee.
  • Add a small regression test whenever a real edge case is discovered; concrete examples preserve the reason behind a guard more reliably than a general comment.