Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Non-Enumerables

reading/non_enumerables.livemd

Non-Enumerables

Mix.install([
  {:jason, "~> 1.4"},
  {:kino, "~> 0.9", override: true},
  {:youtube, github: "brooklinjazz/youtube"},
  {:hidden_cell, github: "brooklinjazz/hidden_cell"}
])

Navigation

Home Report An Issue Tic-tac-toeComprehensions

Review Questions

Upon completing this lesson, a student should be able to answer the following questions.

  • What are some examples of non-enumerable vs enumerable data structures?
  • How do you enumerate over non-enumerable data structures?
  • How do you convert non-enumerable data structures into enumerable data structures?

Overview

Non-Enumerables

Non-enumerable data types are any data type that does not implement the Enumerable protocol. For example, integers, floats, strings, atoms, and tuples are all not enumerable.

Enumeration With Non-Enumerables

To use enumeration with a non-enumerable data type, we need to convert the data into an enumerable data type.

For example, we could convert a string "abc" into a list of characters ["a", "b", "c"] if we wanted to enumerate over each character.

Converting Non-Enumerables Into Enumerables

While we can’t enumerate over non-enumerable data types, Elixir provides many functions we can use to convert non-enumerable data types into enumerable data types.

Integers

We can use the Integer.digits/1 function to convert integers to a list of digits.

Integer.digits(123)

Your Turn

In the Elixir cell below, convert the integer 4389 into a list of digits.

Undigits

We can convert a list of digits back into a single integer using Integer.undigits/2.

Integer.undigits([1, 2, 3])

Tuples

Despite being so similar to lists, tuples are not considered enumerable. That’s primarily because they are intended as fixed-sized containers, and any case that requires enumeration would likely be better served with lists.

To get around this if needed, you can convert a tuple to a list with Tuple.to_list/1.

However, if you find yourself doing this often, it may be a better choice to start with a list instead of a tuple.

Tuple.to_list({1, 2, 3})

We can then convert a list back into a tuple using List.to_tuple/1

List.to_tuple([1, 2, 3])

Strings

Strings are not enumerable.

Enum.map("abc", fn char -> char end)

String.split/3

However, strings can be converted into lists using String.split/3.

String.split/3 splits a string based on some value.

For example, we can split a string by every comma like so:

String.split("a,b,c,d", ",")

We can split a string into a list of characters by splitting on every empty space "" This does create an empty string becaused of the start and the end of the list.

String.split("abcde", "")

You can trim whitespace using the [trim: true] option.

String.split("abcde", "", trim: true)

By default, String.split/1 will split the string on every space.

String.split("hello world")

Now your string is an enumerable list of characters.

Your Turn

In the Elixir cell below, convert the string "Hello, world!" into a list of single characters.

Joining Strings

Once you’ve applied your transformation to the list of string characters, you can rejoin them using Enum.join/2

Enum.join(["a", "b", "c"], "")

The default joiner is a string, so you can omit the second argument.

Enum.join(["a", "b", "c"])

Alternatively we can join the strings by some joining character.

Enum.join(["a", "b", "c"], "_")

We can use String.split/3 and Enum.join/2 in combination with each other to split strings, enumerate over them applying some transformation, and then rejoining them.

Here’s a simple example of replacing all characters other than spaces with "X".

split_string = String.split("secret information", "")

transformed_list =
  Enum.map(split_string, fn char ->
    case char do
      " " -> " "
      _ -> "X"
    end
  end)

joined_string = Enum.join(transformed_list)

Your Turn

Create a CharacterCount module that can count the number of characters in a string.

Example Solution

defmodule CharacterCount do
  def count(string) do
    string
    |> String.split("", trim: true)
    |> Enum.count()
  end
end
defmodule CharacterCount do
  @moduledoc """
  Character Count
  """

  @doc """
  Count the number of characters in a string

  ## Examples

      iex> CharacterCount.count("abc")
      3

      iex> CharacterCount.count("abcd")
      4
  """
  def count(string) do
  end
end

Further Reading

Consider the following resource(s) to deepen your understanding of the topic.

Commit Your Progress

DockYard Academy now recommends you use the latest Release rather than forking or cloning our repository.

Run git status to ensure there are no undesirable changes. Then run the following in your command line from the curriculum folder to commit your progress.

$ git add .
$ git commit -m "finish Non-Enumerables reading"
$ git push

We’re proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace.

We also offer a paid course where you can learn from an instructor alongside a cohort of your peers. We will accept applications for the June-August 2023 cohort soon.

Navigation

Home Report An Issue Tic-tac-toeComprehensions