papasmurf22

papasmurf22

hi everyone,
I have the simple problem of “Find the first recurring character in a string” that I can easily think about solving in an OO language with a for loop and a counter variable but am wondering how you would solve this “the functional way”.

i.e: If “ABCDAHWX” was passed in to the function as argument you would return the first recurring character “A”.

What is the FP way to do this in elixir? Would u use recursion or maybe matching on function parameters?

Thank you for your time

Showing Posts 1 to 10

idi527

idi527

Same way, probably.

defmodule Test do
  def first_recurring(str) do
    do_first_recurring(str, [])
  end

  defp do_first_recurring(<<letter, rest::bytes>>, chars) do
    if letter in chars do
      <<letter>>
    else
      do_first_recurring(rest, [letter | chars])
    end
  end
  defp do_first_recurring("", _chars), do: nil
end

Not particularly efficient, but should provide you with a general idea.

iex(2)> Test.first_recurring("ABCDAHWX")
"A"
LostKobrakai

LostKobrakai

I’d use Enum.reduce_while:

result = Enum.reduce_while(String.graphemes("ABCDAHWX"), [], fn character, prev ->
  if character in prev, do: {:halt, character}, else: {:cont, [character | prev]}
end)

with char when is_binary(char) <- result do
  char
else
  [_ | _] -> :no_duplicates
end
papasmurf22

papasmurf22 OP

awesome thank you. This taught me a bunch of things. Just to be clear, you do “(<<letter, rest::bytes>>, chars)” in the first private function because you’re matching a binary of unknown size?

Thank you

idi527

idi527

Just to be clear, you do “(<<letter, rest::bytes>>, chars)” in the first private function because you’re matching a binary of unknown size?

Yes, I thought letter <> rest would work, but it didn’t …

jamesnorton

jamesnorton

I would uses a regular expression for this.

iex(1)> reg = ~r/(.).*?\1/
~r/(.).*?\1/
iex(2)> s = "ABCDAHWX"
"ABCDAHWX"
iex(3)> Regex.run(reg, s)
["ABCDA", "A"]

The regular expression uses a capture group to match a single character and then a back reference to the captured value to match the repeated character.

papasmurf22

papasmurf22 OP

this seems like a super elegant solution. thank you. if one were a regex beginner are there any resources besides the Elixir Regex docs that you’d recommend?

peerreynders

peerreynders

https://www.regular-expressions.info/

https://regexr.com/ set the RegEx Engine to PCRE (Perl Compatible Regular Expressions)

jamesnorton

jamesnorton

I’m fond of https://elixre.lpil.uk/ as well.

Qqwy

Qqwy

TypeCheck Core Team

When doing it in pure Ellixir, the solutions by @idi527 and @LostKobrakai are, when you use a (map)set to check for duplicates rather than a list, about as fast as you can do it. Of course, I expect the regular expression version to be faster, because it will run closer to the metal (its internal algorithm will however be very similar).

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews