TinyBase

setIndexDefinition

The setIndexDefinition method lets you set the definition of an Index.

setIndexDefinition(
  indexId: string,
  tableId: string,
  getSliceId?: string | (getCell: GetCell, rowId: string) => string,
  getSortKey?: string | (getCell: GetCell, rowId: string) => SortKey,
  sliceIdSorter?: (sliceId1: string, sliceId2: string) => number,
  rowIdSorter?: (sortKey1: SortKey, sortKey2: SortKey, sliceId: string) => number,
): Indexes
TypeDescription
indexIdstring

The Id of the Index to define.

tableIdstring

The Id of the Table the Index will be generated from.

getSliceId?string | (getCell: GetCell, rowId: string) => string

Either the Id of the Cell containing, or a function that produces, the Id that is used to indicate which Slice in the Index the Row Id should be in. Defaults to a function that returns '' (meaning that if this getSliceId parameter is omitted, the Index will simply contain a single Slice containing all the Row Ids in the Table).

getSortKey?string | (getCell: GetCell, rowId: string) => SortKey

Either the Id of the Cell containing, or a function that produces, the value that is used to sort the Row Ids in each Slice.

sliceIdSorter?(sliceId1: string, sliceId2: string) => number

A function that takes two Slice Id values and returns a positive or negative number to indicate how they should be sorted.

rowIdSorter?(sortKey1: SortKey, sortKey2: SortKey, sliceId: string) => number

A function that takes two Row Id values (and a slice Id) and returns a positive or negative number to indicate how they should be sorted.

returnsIndexes

A reference to the Indexes object.

Every Index definition is identified by a unique Id, and if you re-use an existing Id with this method, the previous definition is overwritten.

An Index is a keyed map of Slice objects, each of which is a list of Row Ids from a given Table. Therefore the definition must specify the Table (by its Id) to be indexed.

The Ids in a Slice represent Row objects from a Table that all have a derived string value in common, as described by this method. Those values are used as the key for each Slice in the overall Index object.

Without the third getSliceId parameter, the Index will simply have a single Slice, keyed by an empty string. But more often you will specify a Cell value containing the Slice Id that the Row should belong to. Alternatively, a custom function can be provided that produces your own Slice Id from the local Row as a whole.

The fourth getSortKey parameter specifies a Cell Id to get a value (or a function that processes a whole Row to get a value) that is used to sort the Row Ids within each Slice in the Index.

The fifth parameter, sliceIdSorter, lets you specify a way to sort the Slice Ids when you access the Index, which may be useful if you are trying to create an alphabetic Index of Row entries. If not specified, the order of the Slice Ids will match the order of Row insertion.

The final parameter, rowIdSorter, lets you specify a way to sort the Row Ids within each Slice, based on the getSortKey parameter. This may be useful if you are trying to keep Rows in a determined order relative to each other in the Index. If omitted, the Row Ids are sorted alphabetically, based on the getSortKey parameter.

The two 'sorter' parameters, sliceIdSorter and rowIdSorter, are functions that take two values and return a positive or negative number for when they are in the wrong or right order, respectively. This is exactly the same as the 'compareFunction' that is used in the standard JavaScript array sort method, with the addition that rowIdSorter also takes the Slice Id parameter, in case you want to sort Row Ids differently in each Slice. You can use the convenient defaultSorter function to default this to be alphanumeric.

Examples

This example creates a Store, creates an Indexes object, and defines a simple Index based on the values in the species Cell.

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  cujo: {species: 'dog'},
});

const indexes = createIndexes(store);
indexes.setIndexDefinition('bySpecies', 'pets', 'species');

console.log(indexes.getSliceIds('bySpecies'));
// -> ['dog', 'cat']
console.log(indexes.getSliceRowIds('bySpecies', 'dog'));
// -> ['fido', 'cujo']

This example creates a Store, creates an Indexes object, and defines an Index based on the first letter of the pets' names.

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  cujo: {species: 'dog'},
});

const indexes = createIndexes(store);
indexes.setIndexDefinition('byFirst', 'pets', (_, rowId) => rowId[0]);

console.log(indexes.getSliceIds('byFirst'));
// -> ['f', 'c']
console.log(indexes.getSliceRowIds('byFirst', 'f'));
// -> ['fido', 'felix']

This example creates a Store, creates an Indexes object, and defines an Index based on the first letter of the pets' names. The Slice Ids (and Row Ids within them) are alphabetically sorted.

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  cujo: {species: 'dog'},
});

const indexes = createIndexes(store);
indexes.setIndexDefinition(
  'byFirst', //              indexId
  'pets', //                 tableId
  (_, rowId) => rowId[0], // each Row's sliceId
  (_, rowId) => rowId, //    each Row's sort key
  defaultSorter, //          sort Slice Ids
  defaultSorter, //          sort Row Ids
);

console.log(indexes.getSliceIds('byFirst'));
// -> ['c', 'f']
console.log(indexes.getSliceRowIds('byFirst', 'f'));
// -> ['felix', 'fido']