[]previous and next page

mapArray

Maps each item of a list to a row that lives as long as the item does.

Maps each item of a list to a row that lives as long as the item does. Rows whose key survives an update keep their mapped value; new items get new rows; removed items have their rows disposed.

Unkeyed: rows are matched by item reference, and map receives the item value. Equal primitives pair up in order of occurrence. The returned accessor is lazy and memoized: rows are created and disposed when it is read, so a list nobody reads keeps removed rows alive until the next read.

Keyed form: rows are matched by key(item). map receives an accessor, so a new object under the same key updates item() without re-creating the row. A duplicate key warns in dev and its later copies get fresh rows on every update (dev warning EACH_KEY_DUPLICATE, once). Keys compare like Map keys, so NaN matches NaN.

Import#

ts
import { mapArray } from "@shadow-js/core";

Signature#

ts
function mapArray<T, U>(
  list: ListSource<T>,
  map: (item: T, index: () => number) => U,
  options?: { key?: undefined; fallback?: () => U },
): Accessor<U[]>

function mapArray<T, U>(
  list: ListSource<T>,
  map: (item: () => T, index: () => number) => U,
  options: { key: (item: T) => unknown; fallback?: () => U },
): Accessor<U[]>

Parameters#

Name Description
list Source list. null, undefined and false are an empty list.
map Runs once per new row, untracked, in the row's own root. index() follows the row.
options fallback is shown while the list is empty. Undefined: an empty list maps to [].
list Source list. null, undefined and false are an empty list.
map Runs once per new row, untracked, in the row's own root. item() and index() follow the row.
options key identifies each item and runs untracked; fallback is shown while the list is empty.

Returns#

Accessor of the mapped rows, in the order of the input.

Throws#

  • Nothing itself. Reading the accessor rethrows what map or a row cleanup threw; several errors at once arrive as one AggregateError.
  • Nothing itself. Reading the accessor rethrows what map, key or a row cleanup threw; several errors at once arrive as one AggregateError.

Examples#

ts
import { createRoot, mapArray, useSignal } from "@shadow-js/core";

createRoot(() => {
  const [users] = useSignal([{ name: "Ada" }, { name: "Linus" }]);
  const names = mapArray(users, (user, index) => `${index() + 1}. ${user.name}`);
  console.log(names()); // ["1. Ada", "2. Linus"]
});
ts
import { createRoot, mapArray, useSignal } from "@shadow-js/core";

createRoot(() => {
  const [todos] = useSignal([{ id: 1, title: "Write docs" }]);
  const rows = mapArray(todos, (todo) => `#${todo().id} ${todo().title}`, {
    key: (todo) => todo.id,
  });
  console.log(rows()); // ["#1 Write docs"]
});