JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 4915
  • Score
    100M100P100Q131886F
  • License MIT

Extended native JavaScript Array which provides indexed lookup similar to native Map.

Package Exports

  • indexable-array

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (indexable-array) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Indexable Array

Extended native JavaScript Array which provides indexed lookup similar to native Map.

Commitizen FriendlyConventional Commits

Installation

npm install indexable-array

Description

indexable-array extends native JavaScript array and provides indexed lookup features similar to native Map by using Proxy for shallow change detection.

Synopsis

import IndexableArray, { Self } from "indexable-array";

const users = new IndexableArray({ id: 23, name: "George" }, { id: 92, name: "George" }).addIndex("name", Self);
const otherUsers = new IndexableArray({ id: 12, name: "Hans" }, { id: 18, name: "Tanja" }).addIndex("name").addSelfIndex();

Array.isArray(users); // true
users.getIndex("George"); // 1
users.get("George"); // Get first George: { id: 23, name: "George"}
users.get("George", { fromIndex: 1 }); // Get first George starting from index 1: { id: 23, name: "George"}
users.getAllIndexes("George"); // [0, 1]

// Replace George with Henry
const newUser = { id: 21, name: "Henry" };
users[0] = newUser;
users.getIndex(newUser); // 0 - It is possible to index whole object by { selfIndex: true } option.

// Add another Henry
users.splice(1, 1, { id: 34, name: "Henry" });
users.getAllIndexes("Henry"); // [0, 1];

// You may want to disable en re-enable index for heavy updates for performance reasons.
users.disableIndex(); // Disable index before heavy updates.
// ... many many many updates here
users.enableIndex(); // Index is recreated from scratch.

// Do NOT change deeply nested values in indexed fields.
// users[0].name = "DON'T DO THIS";       // WRONG: Sub fields (i.e. [0]."name") of the array is not watched, so index does not get updated.

// To change nested values use `set()`
users.set(0, "name", "OK"); // Index updated.

// or (not preferred because of expensive index creation for a small update)
users.disableIndex();
users[0].name = "Prefer set()";
users.enableIndex(); // Index is recreated from scratch.

Details

  • Written in TypeScript.
  • Is a native Array (Array.isArray(indexableArray) === true), so supports all array features.
  • 100% test coverage.
  • Tracks all shallow changes via by using Proxy
  • Limited support for updating deep properties via set() method.
  • Uses map to index for very fast lookups.
  • Uses binary search for updates for faster index update.
  • Disables and recreates index from scratch automatically for heavy update operations like splice if above threshold..
  • Indexing may be disabled and re-enabled for heavy update operations manually.
  • Uses binary search for indexOf(), lastIndexOf(), has() if user added self index.
  • Methods such as map(), filter(), slice() returns IndexedArray. Additionally provides mapIndexed() method.

API


IndexableArray

Extended native array class to access array elements by fast key lookups using binary search. Used for storing objects.


new IndexableArray(...items)

Creates an IndexableArray instance from given items.

Param Type Description
...items *

Items to create IndexableArray from.

Example

import IndexableArray, { Self } from "indexable-array";
const users = new IndexableArray({ id: 23, name: "Geroge" }, { id: 96, name: "Lisa" }).addIndex("name");
Array.isArray(users); // true
users.get("George"); // { id: 23, name: "George"}
const user = { id: 21, name: "Henry" };
users[0] = user;
users.getIndex(user); // 0 - It is possible to index whole object by { selfIndex: true } option.
users.splice(1, 1, { id: 34, name: "Henry" });
users.getAllIndexes("Henry"); // [0, 1];

users[0].name = "DON'T DO THIS"; // WRONG: Sub fields (i.e. [0]."name") of the array is not watched, so index does not get updated.
users.set(0, "name", "OK"); // Index updated.
users.disableIndex();
users[0].name = "THIS IS OK NOW";
users.enableIndex(); // Index is recreated from scratch.


indexableArray.indexedKeys : Set.<string>

Set of the indexed key names. $$self is used for the whole value.

Read only
Example

const users = new IndexableArray({ id: 23, name: "Geroge" }, { id: 96, name: "Lisa" }).addSelfIndex().addIndex("name");
users.indexedArray; // ["$$self", "name"]


indexableArray.addIndex(keys) ⇒ this

Adds given keys to the index.

Returns: this -

  • This object.
Param Type Description
keys string, Self

List of keys to add to index.


indexableArray.addIndexFrom(source) ⇒ this

Adds same index types from another IndexableArray.

Returns: this -

  • This object.
Param Type Description
source IndexableArray

IndexableArray to get index keys from.

Example

const users = new IndexableArray({ id: 23, name: "Geroge" }, { id: 96, name: "Lisa" }).addIndex("name");
const other = new IndexableArray().addIndexFrom(users); // Indexes "name".


indexableArray.addSelfIndex() ⇒ this

Adds Self (whole object) to index.

Returns: this -

  • This object.
**Example** ```ts const users = new IndexableArray([{ id: 1, name: "George" }, { id: 2, name: "Lisa" }]).addSelfIndex(); const newUser = { id: 3, name: "George" }; users.push(newUser); users.getIndex(newUser); // 2; ```


indexableArray.map(callbackfn, [thisArg]) ⇒ IndexableArray

Creates a new IndexableArray with the results of calling a provided function on every element in the calling array. Returned IndexedArray does not have any indexes, because callback function may return different kind of elements from source array. To have same indexes as source IndexedArray, use mapWithIndex() instead.

Returns: IndexableArray -

  • A new IndexableArray with each element being the result of the callback function. Returned value has no indexes.
**See**: [indexableArray#mapWithIndex](indexableArray#mapWithIndex) to get an `IndexableArray` with same index keys.
Param Type Description
callbackfn function

Function that produces an element of the new Array, taking three arguments: value, index and indexableArray.

[thisArg] *

Value to use as this when executing callback.

Example

const usersWithName = new IndexableArray({ id: 23, name: "Geroge" }, { id: 96, name: "Lisa" }).addIndex("name");
const usersWithNick = usersWithName.map(user => ({ id: user.id, nick: name.substring(0, 2) })).addIndex("nick"); // Has only "nick" index.


indexableArray.mapWithIndex(callbackfn, [thisArg]) ⇒ IndexableArray

Creates a new IndexableArray with the results of calling a provided function on every element in the calling array. Returned IndexedArray have same indexes as source IndexedArray. To have different indexes than source IndexedArray use map() instead.

Returns: IndexableArray -

  • A new IndexableArray with each element being the result of the callback function. Returned value has same indexes with source IndexedArray.
**See**: [indexableArray#map](indexableArray#map) to get an `IndexableArray` without any index keys.
Param Type Description
callbackfn function

Function that produces an element of the new Array, taking three arguments: value, index and indexableArray.

[thisArg] *

Value to use as this when executing callback.

Example

const usersWithName = new IndexableArray({ id: 23, name: "Geroge" }, { id: 96, name: "Lisa" }).addIndex("name");
const usersTrimmedName = usersWithName.mapWithIndex(user => ({ id: user.id, name: name.trim() })); // Has "name" index already.


indexableArray.concatIndexed(...items) ⇒ IndexableArray

Merges two or more arrays. This method does not change the existing arrays, but instead returns a new array.

Returns: IndexableArray -

  • A new IndexableArray instance with same indexes as source.
Param Type Description
...items *

Arrays and/or values to concatenate into a new array. If all valueN parameters are omitted, concat returns a shallow copy of the existing array on which it is called.


indexableArray.setDefaultIndex(key) ⇒ this

Sets default index key to be used with lookup functions such as [get](#IndexableArray+get), [getAll](#IndexableArray+getAll), [getIndex](#IndexableArray+getIndex), [getAllIndexes](#IndexableArray+getAllIndexes) etc. If not set, IndexedArray uses first indexable key as default key.

Returns: this -

  • This value.
Param Type Description
key string

Default key to be used with lookup functions.

Example

const input = [{ id: 23, name: "Geroge" }, { id: 96, name: "Lisa" }];
const users = new IndexableArray(...input).addIndex("name", "id"); // "name" is default index
users.setDefaultIndex("id"); // "id" is default index.


indexableArray.getIndex(value, [options]) ⇒ number

Returns the first index at which a given indexed value can be found in the array, or -1 if it is not present.

Returns: number -

  • The first index of the element in the array; -1 if not found.
Param Type Description
value *

Indexed value to search for.

[options] Object

Options

[options.key] string

Index field to look for value. Default lookup field is used if no key is provided.

[options.fromIndex] number

The index to start the search at. If the index is greater than or equal to the array's length, -1 is returned, which means the array will not be searched. If the provided index value is a negative number, it is taken as the offset from the end of the array


indexableArray.getAllIndexes(value, [options]) ⇒ Array.<number>

Returns all indexes at which a given indexed value can be found in the array, or empty array if it is not present.

Returns: Array.<number> -

  • All indexes of the element in the array; Empty array if not found.
Param Type Description
value *

Indexed value to search for.

[options] Object

Options

[options.key] string

Index field to look for value. Default lookup field is used if no key is provided.


indexableArray.get(value, [options]) ⇒ Object | undefined

Returns the first item at which a given indexed value can be found in the array, or undefined if it is not present.

Returns: Object | undefined -

  • The first item with given indexed value in the array; undefined if not found.
Param Type Description
value *

Indexed value to search for.

[options] Object

Options

[options.key] string

Index field to look for value. Default lookup field is used if no key is provided.

[options.fromIndex] number

The index to start the search at. If the index is greater than or equal to the array's length, -1 is returned, which means the array will not be searched. If the provided index value is a negative number, it is taken as the offset from the end of the array


indexableArray.getAll(value, [options]) ⇒ Array.<number>

Returns all items at which a given indexed value can be found in the array, or empty array if it is not present.

Returns: Array.<number> -

  • All items with given indexed value in the array; Empty array if not found.
Param Type Description
value *

Indexed value to search for.

[options] Object

Options

[options.key] string

Index field to look for value. Default lookup field is used if no key is provided.


indexableArray.has(value, [options]) ⇒ boolean

Determines whether an array includes a certain indexed value among its entries' keys, returning true or false as appropriate.

Returns: boolean -

  • True if indexed value is found among array's entries' keys.
Param Type Description
value *

Indexed value to search for.

[options] Object

Options

[options.key] string

Index field to look for value. Default lookup field is used if no key is provided.

[options.fromIndex] number

The index to start the search at. If the index is greater than or equal to the array's length, -1 is returned, which means the array will not be searched. If the provided index value is a negative number, it is taken as the offset from the end of the array


indexableArray.set(position, path, value) ⇒ void

Sets value at path of the object, which is one of the entires of array. To update fields of the objects, this method should be used. Otherwise index cannot be updated, because sub fileds are not tracked for chage detection.

Param Type Description
position number

Index of the item to be changed.

path string

Item's path where value to be changed at.

value *

New value to be assigned.

Example

indexedArray[0].name = "DON'T DO THIS"; // WRONG: Sub fields (i.e. [0]."name") of the array is not watched, so index does not get updated.
indexedArray.set(0, "name", "OK"); // Index updated.


indexableArray.disableIndex()

Disables indexing of the array. It may be used to disable temporarily

  • to do heavy updates for performance reasons,
  • to do operations in sub fields. If indexing is not needed anymore, it is suggested to create a new native non-extended array and copy values into it for avoiding performance penalty of proxy array used in this library.

See: {IndexedArray#enableIndex} method.
Example

indexedArray.disableIndex();
indexedArray[0].name = "THIS IS OK NOW";
indexedArray.enableIndex(); // Index is recreated from scratch.


indexableArray.enableIndex()

Enables indexing and recreates index from scratch.

See: {IndexedArray#disableIndex} method.


IndexableArray.from(arrayLike, [mapFn], [thisArg]) ⇒ IndexableArray

Creates a new, shallow-copied IndexableArray instance from an array-like or iterable object. If source is also IndexableArray, returned IndexableArray will have same indexed keys.

Returns: IndexableArray -

  • A new IndexableArray instance.
Param Type Description
arrayLike Iterable, ArrayLike

An array-like or iterable object to convert to an array.

[mapFn] function

Map function to call on every element of the array.

[thisArg] *

Value to use as this when executing mapFn.