CxJS

diffArrays

import { diffArrays } from 'cx/data'; Copied

diffArrays compares two arrays and returns the differences: added, changed, unchanged, and removed items.

<div controller={PageController}>
  <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px">
    <div>
      <h4 style="margin: 0 0 8px">Old Array</h4>
      <Grid
        records={m.oldItems}
        columns={[
          { header: "ID", field: "id" },
          { header: "Name", field: "name" },
        ]}
      />
    </div>
    <div>
      <h4 style="margin: 0 0 8px">New Array</h4>
      <Grid
        records={m.newItems}
        columns={[
          { header: "ID", field: "id" },
          { header: "Name", field: "name" },
        ]}
      />
    </div>
  </div>

  <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 16px">
    <div>
      <h4 style="margin: 0 0 8px; color: green">Added</h4>
      <Grid
        records={m.diff.added}
        columns={[
          { header: "ID", field: "id" },
          { header: "Name", field: "name" },
        ]}
      />
    </div>
    <div>
      <h4 style="margin: 0 0 8px; color: orange">Changed</h4>
      <Grid
        records={m.diff.changed}
        columns={[
          { header: "Before", field: "before.name" },
          { header: "After", field: "after.name" },
        ]}
      />
    </div>
    <div>
      <h4 style="margin: 0 0 8px; color: gray">Unchanged</h4>
      <Grid
        records={m.diff.unchanged}
        columns={[
          { header: "ID", field: "id" },
          { header: "Name", field: "name" },
        ]}
      />
    </div>
    <div>
      <h4 style="margin: 0 0 8px; color: red">Removed</h4>
      <Grid
        records={m.diff.removed}
        columns={[
          { header: "ID", field: "id" },
          { header: "Name", field: "name" },
        ]}
      />
    </div>
  </div>

  <div style="display: flex; gap: 8px; flex-wrap: wrap">
    <Button onClick="scenario1">Add Items</Button>
    <Button onClick="scenario2">Remove Items</Button>
    <Button onClick="scenario3">Mixed Changes</Button>
    <Button onClick="reset">Reset</Button>
  </div>
</div>

Old Array

IDName
1Apple
2Banana
3Cherry

New Array

IDName
1Apple
2Blueberry
4Date

Added

IDName
4Date

Changed

BeforeAfter
BananaBlueberry

Unchanged

IDName
1Apple

Removed

IDName
3Cherry

Signature

function diffArrays<T>(
  oldArray: T[],
  newArray: T[],
  keyFn?: (item: T) => any,
): DiffResult<T>;

interface DiffResult<T> {
  added: T[];
  changed: { before: T; after: T }[];
  unchanged: T[];
  removed: T[];
}

Parameters

ParameterTypeDefaultDescription
oldArrayT[]The original array.
newArrayT[]The new array to compare against.
keyFnfunction(e) => eFunction to extract unique key from item.

Return Value

Returns an object with four arrays:

PropertyTypeDescription
addedT[]Items in new array but not in old.
changed{ before: T; after: T }[]Items with same key but different reference.
unchangedT[]Items with same key and reference.
removedT[]Items in old array but not in new.

Examples

With objects

const old = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
];

const updated = [
  { id: 1, name: "Alice" }, // unchanged (same reference)
  { id: 2, name: "Bobby" }, // changed (different object)
  { id: 3, name: "Carol" }, // added
];

const diff = diffArrays(old, updated, (item) => item.id);
// {
//   added: [{ id: 3, name: "Carol" }],
//   changed: [{ before: { id: 2, name: "Bob" }, after: { id: 2, name: "Bobby" } }],
//   unchanged: [{ id: 1, name: "Alice" }],
//   removed: []
// }

With primitives

const old = [1, 2, 3];
const updated = [2, 3, 4];

const diff = diffArrays(old, updated);
// {
//   added: [4],
//   changed: [],
//   unchanged: [2, 3],
//   removed: [1]
// }

Use Cases

  • Synchronizing local state with server data
  • Showing what changed after an edit
  • Optimizing updates by only processing changed items
  • Generating change logs or audit trails

See Also