How to `get` or `remove` the first matched element in a list without traverse it?

Thank you for your work, but I think the best way to achieve performance is Elixir provides first match return high order functions, they’re may be implemented by C, than used as raw functions.

What do you mean by first match return?

The result is returned when the first match is made. :grin:
Just like use for & break syntax in mutable languages.
In C, when you do operations on list, you can remove an element and cons list at the same time.

Yeah, but you also need to modify the structure when the first match is found (like in pop). This is not an easy task in an immutable language with immutable structures

For example, the list works like a “persistent stack” data structure. This means that straightforward C-linked-list-style deletion of a value in a list will break all other versions using this list. So NIF is not a solution here

Anyway, Erlang (and Elixir) were never meant to be extremely performant. That’s why I’ve created Pathex, to acheive the best performance without writing NIFs or breaking the laws of BEAM. And I think Pathex does a pretty good job. For example, viewing and setting values with Pathex is faster than with Clojure’s Spectre library, even though the structures access code in Clojure is jitted with more serious optimizations than in Elixir/Erlang

1 Like

Yeah, I fully agree, what Elixir really attracted me is not the speed, you know what I mean~ :grin:

Yeah, I fully agree, what Elixir really attract me is not the speed, you know what I mean~ :grin:
Pathex.pop or Enum.group both are OK for me. :wink:

1 Like

I’m trying to do the same thing.

What’s wrong with the following?

    {first, rest} =
      case Enum.find(list, predicate) do
        nil -> {nil, list}
        found -> {found, list -- [found]}
      end

Nothing wrong, it is just not the most efficient solution. There will be two traversals and comparsion in -- will take some time possibly

1 Like

Wonder why nobody mentioned Erlang’s :queue module, or @ferd’s zippers repo. They all seem to promise more efficient implementations of lists that need regular manipulation that’s not only at the front (which is where Erlang’s builtin singly-linked lists excel at… but nowhere else).

1 Like

Good suggestions above but I’d also give the built-in array module a try. You can “void” entries at specific index and then skip them with the sparse_* functions.

1 Like