How to get list elements by index in elixir

33,038

You can use pattern matching for that:

[from, to] = String.split line, " "

Maybe you want to add parts: 2 option to ensure you will get only two parts in case there is more than one space in the line:

[from, to] = String.split line, " ", parts: 2

There is also Enum.at/3, which would work fine here but is unidiomatic. The problem with Enum.at is that due to the list implementation in Elixir, it needs to traverse the entire list up to the requested index so it can be very inefficient for large lists.


Edit: here's the requested example with Enum.at, but I would not use it in this case

parts = String.split line, " "
from = Enum.at(parts, 0)
to = Enum.at(parts, 1)
Share:
33,038
posixpascal
Author by

posixpascal

#☝️ Hi. I like emojis, open source projects, breaking things, writing tests, blaming the compiler and other stuff you usually read in this section from a developer. Turning ☕️ caffeine into code for about 14 years now. JavaScript and Ruby enthusiast. But more JavaScript than Ruby. Fluent in PHP, Python and Shell scripts and whatever you see on my GitHub. ❤️ Things I love I love Web, APIs, Backends, aws, good stuff. Terraform, Nuxt, React. Hop on the event bus and drive down microservice lane. Big fan of Sandi Metz's work and talks. I love cats, but don't have one. I would call her Knuckles tho. So I built some more or less cat related projects like... 📍A Multiplayer Geographical Guessing Game @ geofind.io 🗺 A Smart Wiki-Based Audio Tour Guide 🐈 A peer 2 peer filesharing service called peer.cat. 🍕 Built a B2B POS Platform mainorder.de 🕵️ Found Lovoo privacy vulnerability 🤞 Being transparent at my personal site. Play Chess with me! 🔨 Made my personal dotfiles repo Built lots of sites, platforms, apps as well, checkout my github. Deal is simple: Give me code and I fix your stuff, or I fix my own stuff, or build something nice on top of your project, or build something broken on top of it. Depends on the amount of coffee you feed me basically. 📖 Quotes people love 🚧 Move fast, break things. and 😐 Why would jenkins do this 🗣 Chit-chat Just drop me a message anywhere you like. Otherwise, feel free to do whatever you want.

Updated on July 09, 2022

Comments

  • posixpascal
    posixpascal over 1 year
    {status, body} = File.read("/etc/hosts")
    if status == :ok do
        hosts = String.split body, "\n"
        hosts = Enum.map(hosts, fn(host) -> line_to_host(host) end)
    else
        IO.puts "error reading: /etc/hosts"
    end
    

    I have the following elixir function where I read the /etc/hosts file and try to split it line by line using String.split.

    Then I map through the line list of hosts and call line_to_host(host) for each. The line_to_host method splits the line by " " and then I want to set the from and to variable:

    def line_to_host(line) do
        data = String.split line, " "
        from = elem(data, 0) // doesn't work
        to = elem(data, 1) // doesn't work either
        %Host{from: from, to: to}
    end
    

    I looked through stackoverflow, the elixir docs and googled about how to get an list element at a specific index. I know there is head/tail but there has to be a better way of getting list elements.

    elem(list, index) does exactly what I need but unfortunately it's not working with String.split.

    How to get list/tuple elements by ID in elixir

  • posixpascal
    posixpascal about 8 years
    I'm a bit unsatisfied by this solution. Isn't it possible to just get the X part of that String.split returns? Enum.at didn't work with String.split.
  • Patrick Oscity
    Patrick Oscity about 8 years
    Enum.at should work just fine. I'll add an example to my answer. Keep in mind, it is very unidiomatic to use Enum.at in Elixir, if it can be solved otherwise.
  • W.M.
    W.M. about 7 years
    How to make Enum.map from second item in array (i.e. skipping the first one)?
  • Patrick Oscity
    Patrick Oscity about 7 years
    @W.M. I am not sure I understand your question correctly, it seems unrelated to this. You should probably post a new question with example input, expected output and what you have tried so far.
  • W.M.
    W.M. about 7 years
    @PatrickOscity I meant how to loop through an object array skipping the first item (at position 0), i.e. Enum.map without the first item in the array.
  • Patrick Oscity
    Patrick Oscity about 7 years
    @W.M. You can either do [head | tail].= list (If you need the first element, head, as well) or tail = tl(list) (if you don't need the head) to get the tail of a list, then just map over that.