array_vector v0.2.1 Vector

Functions that work on vectors.

This datastructure wraps Erlang’s array type for fast random lookup and update to large collections.

The point of this module is not meant to be a 1:1 wrapper, but to be a useful set of higher-level API operations.

Note that this module is implemented as a struct with an array field, pointing to the underlying Erlang array implementation. This field is private, so you should use the functions in this module to perform operations.

Link to this section Summary

Functions

Append an item to to a vector

Returns either the vector without the value at index, or the original vector if no value is present at index

Finds the element at the given index (zero-based) in logarithmic time. Returns {:ok, element} if found, otherwise :error

Finds the element at the given index (zero-based) in logarithmic time

Gets the value at an index in logarithmic time, returning a default if it does not exist

Gets and updates a value at the same time

Map a vector

Checks if vector contains value

Constructs a array-backed vector

Deletes a value at index, returning the new vector and the value that was deleted

Puts the given value under index in vector in logarithmic time

Reverse a vector

Returns the size of a vector

Converts a vector to a list

Updates the value in vector with the given function in logarithmic time

Updates index with the given function in logarithmic time

Link to this section Types

Link to this type index()
index() :: integer
Link to this type t()
t() :: %Vector{array: :array.array}
Link to this type value()
value() :: term

Link to this section Functions

Link to this function append(vector, value)
append(t, value) :: t

Append an item to to a vector

Examples

iex> Vector.new([1, 2, 3]) |> Vector.append(9)
Vector.new([1, 2, 3, 9])

iex> Vector.new() |> Vector.append("hi")
Vector.new(["hi"])

iex> Vector.new([1, 2, 3]) |> Vector.append(9) |> Vector.size
4
Link to this function delete(vector, index)
delete(t, index) :: t

Returns either the vector without the value at index, or the original vector if no value is present at index.

Examples

iex> Vector.delete(Vector.new([1,2,3,4,5]), 2)
#Vector<[1, 2, 4, 5]>

iex> Vector.delete(Vector.new([1,2,3]), 9)
#Vector<[1, 2, 3]>
Link to this function fetch(vector, index)
fetch(t, index) :: {:ok, value} | :error

Finds the element at the given index (zero-based) in logarithmic time. Returns {:ok, element} if found, otherwise :error.

A negative index can be passed, in which case the index is counted from the end (e.g. -1 finds the last element).

Examples

iex> Vector.fetch(Vector.new([1,2,3]), 9)
:error

iex> Vector.fetch(Vector.new([1,2,3]), 2)
{:ok, 3}

iex> Vector.fetch(Vector.new([1,2,3,4,5]), -2)
{:ok, 4}
Link to this function fetch!(vector, index)
fetch!(t, index) :: value | no_return

Finds the element at the given index (zero-based) in logarithmic time.

Raises OutOfBoundsError if the given index is outside the range of the enumerable.

A negative index can be passed, in which case the index is counted from the end (e.g. -1 finds the last element).

Examples

iex> Vector.fetch!(Vector.new([1,2,3]), 1)
2

iex> Vector.fetch!(Vector.new([1,2,3]), -1)
3

iex> Vector.fetch!(Vector.new([1,2,3]), 99)
** (Enum.OutOfBoundsError) out of bounds error
Link to this function get(vector, index, default \\ nil)
get(t, index, default :: value) :: value

Gets the value at an index in logarithmic time, returning a default if it does not exist.

Examples

iex> Vector.get(Vector.new([1,2,3]), 0)
1

iex> Vector.get(Vector.new([1,2,3]), 9)
nil

iex> Vector.get(Vector.new([1,2,3]), 9, 1000)
1000
Link to this function get_and_update(vector, index, fun)
get_and_update(t, index, (value -> {value, value} | :pop)) :: {value, t}

Gets and updates a value at the same time.

Examples

iex> {val, new_vector} = Vector.get_and_update(Vector.new([1,2,3]), 0, fn(value) -> {value, value + 100} end)
iex> {val, Vector.to_list(new_vector)}
{1, [101, 2, 3]}

iex> {val, new_vector} = Vector.get_and_update(Vector.new([1,2,3]), 0, fn(_) -> :pop end)
iex> {val, Vector.to_list(new_vector)}
{1, [2, 3]}
Link to this function map(vector, fun)

Map a vector.

Examples

iex> Vector.new() |> Vector.map(fn(_i, val) -> val + 1 end)
#Vector<[]>

iex> Vector.new([1, 2, 3]) |> Vector.map(fn(_i, val) -> val + 1 end)
#Vector<[2, 3, 4]>
Link to this function member?(vector, value)

Checks if vector contains value

Examples

iex> Vector.member?(Vector.new([1,2,3]), 99)
false

iex> Vector.member?(Vector.new([1,2,3]), 2)
true

Constructs a array-backed vector

Examples

iex> Vector.new()
#Vector<[]>

iex> Vector.new(Vector.new())
#Vector<[]>

iex> Vector.new([1,2,3])
#Vector<[1, 2, 3]>

iex> Vector.new(%{a: 1, b: 2})
#Vector<[a: 1, b: 2]>

iex> Vector.new(0)
#Vector<[]>

# this is exposing a bit of implementation, but I am
# unsure how else to test it
iex> Vector.new(5).array
{:array, 5, 10, :undefined, 10}
Link to this function pop(vector, index, default \\ nil)

Deletes a value at index, returning the new vector and the value that was deleted

Examples

iex> {value, new} = Vector.pop(Vector.new([1,2,3]), 2)
iex> {value, Vector.to_list(new)} # arrays cannot be checked for value equality
{3, [1, 2]}

iex> {value, new} = Vector.pop(Vector.new([1,2,3]), 99)
iex> {value, Vector.to_list(new)}
{nil, [1, 2, 3]}
Link to this function put(vector, index, value)
put(t, index, value) :: t

Puts the given value under index in vector in logarithmic time

A negative index can be passed, in which case the index is counted from the end (e.g. -1 finds the last element).

Examples

iex> Vector.put(Vector.new([1,2,3]), 3, 99)
#Vector<[1, 2, 3, 99]>

iex> Vector.put(Vector.new([1,2,3]), 0, 3)
#Vector<[3, 2, 3]>

iex> Vector.put(Vector.new([1,2,3]), -1, 101)
#Vector<[1, 2, 101]>
Link to this function reverse(vector)

Reverse a vector.

Examples

iex> vector = Vector.new([1,2,3])
iex> vector == vector |> Vector.reverse |> Vector.reverse
true

iex> Vector.reverse(Vector.new())
#Vector<[]>

iex> Vector.reverse(Vector.new([1, 2, 3]))
#Vector<[3, 2, 1]>

Returns the size of a vector

Examples

iex> Vector.size(Vector.new())
0

iex> Vector.size(Vector.new([1,2,3,4,5]))
5
Link to this function to_list(vector)

Converts a vector to a list

Examples

iex> Vector.to_list(Vector.new([1,2,3]))
[1,2,3]
Link to this function update(vector, index, initial, fun)
update(t, index, value, (value -> value)) :: t

Updates the value in vector with the given function in logarithmic time.

If index is present in vector with value, fun is invoked with argument value and its result is used as the new value of index. If index is not present in vector, initial is inserted as the value of index.

A negative index can be passed, in which case the index is counted from the end (e.g. -1 finds the last element).

Examples

iex> Vector.update(Vector.new([1,2,3]), 0, 13, &(&1 * 2))
#Vector<[2, 2, 3]>

iex> Vector.update(Vector.new([1,2,3]), 5, 11, &(&1 * 2))
#Vector<[1, 2, 3, 11]>

iex> Vector.update(Vector.new([1,2,3]), -2, 11, &(&1 * 2))
#Vector<[1, 4, 3]>
Link to this function update!(vector, index, fun)
update!(t, index, (value -> value)) :: t | no_return

Updates index with the given function in logarithmic time.

If index is present in map with value value, fun is invoked with argument value and its result is used as the new value of index. If index is not present in map, a Enum.OutOfBoundsError exception is raised.

Examples

iex> Vector.update!(Vector.new([1,2,3]), 0, &(&1 * 2))
#Vector<[2, 2, 3]>

iex> Vector.update!(Vector.new([1,2,3]), 5, &(&1 * 2))
** (Enum.OutOfBoundsError) out of bounds error

iex> Vector.update!(Vector.new([1,2,3]), -2, &(&1 * 2))
#Vector<[1, 4, 3]>