# fractional_indexing
[](https://hex.pm/packages/fractional_indexing)
[](https://hexdocs.pm/fractional_indexing/)
This is based on [Implementing Fractional Indexing](https://observablehq.com/@dgreensp/implementing-fractional-indexing) by David Greenspan.
Fractional indexing is a technique to create an ordering that can be used for [Realtime Editing of Ordered Sequences](https://www.figma.com/blog/realtime-editing-of-ordered-sequences/). Essentially, it is a method to maintain an ordered list in an eventually consistent state that will preserve the order of the elements and allow arbitrary insertion of elements anywhere in the list.
The keys are strings that sort lexicographically. Given any key or pair of keys, you can generate a new key that will sort before, after, or between two keys. This allows you to maintain constant key IDs for items in your list while maintaining the ability to add new items in the middle of the list. When working with dynamic JS frontends, this can be useful as an ordering key that prevents extra renders.
This implementation includes variable-length integers to minimize the length of the key as described in the first link.
```sh
gleam add fractional_indexing@1
```
## Example
```gleam
import fractional_indexing as fi
// start with a list of items
let items = [1, 3]
// create some keys for them, here we will use the bulk API
// to generate several keys at once and zip them up
let keys = fi.n_first(num_keys: items |> list.length)
let zipped = list.zip(keys, items)
// [#("a0", 1), #("a1", 3)]
// now you want to add an item between these two values, so
// generate a key to index between `a0` and `a1`. Note
// that key generation can fail in exotic situations, but under
// normal use should return a suitable key
let assert [key1, key2] = keys // a0, a1
let assert Ok(key_between) = fi.between(key1, key2)
let zipped = [#(key_between, 2), ..zipped]
// sort them to get them in the order you want using string comparison
// for the keys
echo zipped |> list.sort(by: fn(a, b) { string.compare(a.0, b.0) })
// [#("a0", 1), #("a0V", 2) #("a1", 3)]
```
Further documentation can be found at <https://hexdocs.pm/fractional_indexing>.
## Development
```sh
gleam run # Run the project
gleam test # Run the tests
```