Home // Posts // Projects // About
Do you find the ==
operator to be too strict? Do you often dream of two values being equal even
though they are completely different types, or of maps being equal to absolutely nothing?
Thankfully, Elixir lets us un-import Kernel.==/2
and define our own.
defmodule JSEquality do def a == b, do: equal?(a, b) or equal?(b, a) def a != b, do: not __MODULE__.==(a, b) def a === b, do: strictly_equal?(a, b) or strictly_equal?(b, a) def a !== b, do: not __MODULE__.===(a, b) defp equal?(1, x) when x in [true, 1], do: true defp equal?(0, x) when x in [false, 0], do: true defp equal?("1", x) when x in [true, 1, "1"], do: true defp equal?("0", x) when x in [false, 0, "0"], do: true defp equal?("", x) when x in [false, 0, ""], do: true defp equal?(:undefined, x) when x in [nil, :undefined], do: true defp equal?(:Infinity, :Infinity), do: true defp equal?(:negative_Infinity, :negative_Infinity), do: true defp equal?([], x) when x in [false, 0, ""], do: true defp equal?([[]], x) when x in [false, 0, ""], do: true defp equal?([0], x) when x in [false, 0, "0"], do: true defp equal?([1], x) when x in [true, 1, "1"], do: true defp equal?(:NaN, _), do: false defp equal?(int, x) when is_integer(int), do: Kernel.==(int, x) or Kernel.==(Integer.to_string(int), x) defp equal?(list, _) when is_list(list), do: false defp equal?(map, _) when is_map(map), do: false defp equal?(x, x), do: true defp equal?(_, _), do: false defp strictly_equal?(list, _) when is_list(list), do: false defp strictly_equal?(map, _) when is_map(map), do: false defp strictly_equal?(:NaN, _), do: false defp strictly_equal?(x, x), do: true defp strictly_equal?(_, _), do: false end
And, in use:
iex> import Kernel, except: [==: 2, !=: 2, ===: 2, !==: 2] Kernel iex> import JSEquality JSEquality iex> "hello" == "hello" true iex> "hello" == :world false iex> :undefined == nil true iex> "1" == [1] true iex> %{} == %{} false iex> false == "0" true iex> [] == [] false iex> [[]] == false true iex> "" == 0 true iex> -123 == "-123" true iex> :NaN == :NaN false iex> "foo" === "foo" true iex> -1 === "-1" false iex> [] === [] false