Skip to main content

README.md

# Algo

Algo is a Elixir utility library for working with nested maps, keyword
lists, lists, enumerables, and strings.

It's inspired by Ramda.js and provides for fairly common data manipulation 
needs which aren't covered by Elixir's `Enum` module and the standard library: 
nested path access, deep merging, projection, list pairing, set-like list comparison 
by key, accumulator mapping, and human-readable string formatting.

## Installation

Add `:algo` to your dependencies:

```elixir
def deps do
  [
    {:algo, "~> 0.1.0"}
  ]
end
```

## Usage

All the functions are available from the top-level `Algo` module (with the exception of `Algo.Alt` - see Naming section below):

```elixir
iex> user = %{profile: %{name: "Ada", role_id: "admin"}}
iex> Algo.get_path(user, [:profile, :name])
"Ada"

iex> Algo.put_path(user, [:profile, :active?], true)
%{profile: %{active?: true, name: "Ada", role_id: "admin"}}
```

The same path helpers work with maps and keyword lists, including mixed nested
structures:

```elixir
iex> data = [user: %{profile: [name: "Ada"]}]
iex> Algo.fetch_path(data, [:user, :profile, :name])
{:ok, "Ada"}
```

List and enumerable helpers cover common collection transformations:

```elixir
iex> Algo.get_unique_pairs([:a, :b, :c], :tuples)
[{:a, :b}, {:a, :c}, {:b, :c}]

iex> Algo.index_by([%{id: 1, name: "Ada"}, %{id: 2, name: "Grace"}], & &1.id)
%{1 => %{id: 1, name: "Ada"}, 2 => %{id: 2, name: "Grace"}}
```

String helpers include both UK and US spellings where useful:

```elixir
iex> Algo.humanise("author_id")
"Author"

iex> Algo.humanize("thisIsDDOSAttack")
"This is DDOS attack"
```

## Examples 

For examples that combine multiple `Algo` functions, see `examples/`. 

## Naming

`Algo` uses verb-oriented operation names such as `get_path/3`, `put_path/3`,
`delete_path/2`, and `transpose/1`.

`Algo.Alt` provides thin aliases whose names describe the returned value or
immutable result:

```elixir
iex> Algo.Alt.value_at_path(%{a: %{b: 1}}, [:a, :b])
{:ok, 1}

iex> Algo.Alt.with_path(%{a: 1}, [:b], 2)
%{a: 1, b: 2}
```

Both styles delegate to the same implementation. I prefer the `Algo.Alt` style as it 
highlights that the functions are pure and the data is immutable. 

## Documentation

The full API reference is published on HexDocs:

<https://hexdocs.pm/algo>

The package page is:

<https://hex.pm/packages/algo>