Reputation: 21
Does Elixir handle matching values relative to constants in any way? An example of this would be ::
All the examples are a pseudo syntax for the idea
[ _ | [ 3 | [ x | _ ] ] ] = [1,2,3,4,5,6,7] // x = 4
[ _ | [ x | [ 6 | _ ] ] ] = [1,2,3,4,5,6,7] // x = 5
[ _ | [ 3 | [ x | [ 6 | _ ] ] ] ] = [1,2,3,4,5,6,7] // x = [4,5]
[ _ | [ 3 | [ [a,b,c] | _ ] ] = [1,2,3,4,5,6,7] // x = [5,6,7]
Unfortunately most books and online documentation only covers absolute positioning from the first index, such as N elements from the head via [ head | tail ]
but as the target value gets farther from the first element this becomes kinda silly with syntax like [ _ | [ _ | [ _ | [ x | _ ] ] ] ]
to get the 4th element in a list.
Is there any syntax for matching relative indexes of a list? An example of incorrect but conceptually plausible syntax would be getting the last index in a list via [ _ | [ x | [] ] ]
or getting the value after the index of 3 via [ _ | [ 3 | [ x | _ ] ] ]
Upvotes: 0
Views: 499
Reputation: 121000
You are abusing pattern matching as it is known in Elixir. When you are interested in finding values across the list, there is no pattern.
— (the value after) 3 = x
iex> [_, x | _] = Enum.drop_while([1,2,3,4,5,6,7], fn e -> e != 3 end)
#⇒ x = 4
— (the value before 6) = x
iex> [x | _] = [1,2,3,4,5,6,7]
...> |> Enum.take_while(fn e -> e != 6 end)
...> |> Enum.reverse
#⇒ x = 5
— (the sublist of values between 3 and 6) = x
iex> [_ | x] = [1,2,3,4,5,6,7]
...> |> Enum.drop_while(fn e -> e != 3 end)
...> |> Enum.take_while(fn e -> e != 6 end)
#⇒ x = [4, 5]
— (the sublist of the 3 values after 4) = [a,b,c]
iex> [1,2,3,4,5,6,7]
...> Enum.drop_while(fn e -> e != 4 end)
...> Enum.slice(1..3)
#⇒ [5,6,7]
Enum
.
Upvotes: 1
Reputation: 222128
Elixir/Erlang do not support pattern matching an item at an unknown position in a list, so none of the 4 cases you mentioned can be done with pattern matching.
The only thing that can be simplified is where you want the 4th element of a list. Instead of:
[_ | [_ | [_ | [x | _]]]]
you can use the pattern:
[_, _, _, x | _]
iex(1)> [_, _, _, x | _] = [1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
iex(2)> x
4
Upvotes: 1