Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching during pipe

Tags:

elixir

I've to parse an xml document, extracting an integer from an xml node.

Currently I have:

try do
  Floki.find(node, "stat[type='jersey_num']")
    |> Floki.text
    |> Integer.parse
    |> elem(0)
rescue
  e -> nil
end

which works fine but I don't like having to rescue everything, I would like to do something like:

Floki.find(node, "stat[type='jersey_num']")
  |> Floki.text
  |> case Integer.parse do
    { int, _binary } -> int
    _                -> nil
  end

but I get unhandled operator -> in the fourth line, is there a way to do this?

like image 391
alex88 Avatar asked Apr 23 '16 06:04

alex88


People also ask

What is pattern matching in Elixir?

Pattern matching allows developers to easily destructure data types such as tuples and lists. As we will see in the following chapters, it is one of the foundations of recursion in Elixir and applies to other types as well, like maps and binaries.

Why ++ is not allowed in pattern matching?

You can only pattern-match on data constructors, and ++ is a function, not a data constructor. Data constructors are persistent; a value like 'c':[] cannot be simplified further, because it is a fundamental value of type [Char] .


1 Answers

You need to pipe into Integer.parse first and then into case:

defmodule MyInteger do
  def parse(string) do
    string
    |> Integer.parse
    |> case do
         {int, _} -> int
         _ -> nil
       end
  end
end

Demo:

iex(1)> MyInteger.parse "123"
123
iex(2)> MyInteger.parse "abc"
nil

Note that MyInteger.parse "123abc" #=> 123, so you might want to change your pattern match to be {int, ""} -> int, if you want the same behavior as Integer.parse/1.

like image 143
Dogbert Avatar answered Oct 01 '22 04:10

Dogbert