Elixir 列表模式匹配 ~ 在使用列表模式匹配常量后得到 x
Posted
技术标签:
【中文标题】Elixir 列表模式匹配 ~ 在使用列表模式匹配常量后得到 x【英文标题】:Elixir list pattern matching ~ get x after constant with list pattern matching 【发布时间】:2017-06-11 18:23:01 【问题描述】:Elixir 是否以任何方式处理与常量相关的匹配值? 这方面的一个例子是 ::
所有的例子都是这个想法的伪语法
(之后的值)3 = x iex>[ _ | [ 3 | [ x | _ ] ] ] = [1,2,3,4,5,6,7] // x = 4
(6之前的值)=x
iex> [ _ | [ x | [ 6 | _ ] ] ] = [1,2,3,4,5,6,7] // x = 5
(3 到 6 之间的值的子列表)= x
iex> [ _ | [ 3 | [ x | [ 6 | _ ] ] ] ] = [1,2,3,4,5,6,7] // x = [4,5]
(4后3个值的子列表)= [a,b,c]
iex> [ _ | [ 3 | [ [a,b,c] | _ ] ] = [1,2,3,4,5,6,7] // x = [5,6,7]
不幸的是,大多数书籍和在线文档仅涵盖从第一个索引开始的绝对定位,例如通过 [ head | tail ]
从头部开始的 N 个元素,但随着目标值离第一个元素越来越远,使用 [ _ | [ _ | [ _ | [ x | _ ] ] ] ]
之类的语法变得有点愚蠢获取列表中的第 4 个元素。
是否有任何语法可以匹配列表的相对索引?一个不正确但在概念上合理的语法示例是通过 [ _ | [ x | [] ] ]
获取列表中的最后一个索引或通过 [ _ | [ 3 | [ x | _ ] ] ]
获取索引 3 之后的值
【问题讨论】:
请提供示例输入和预期输出,真的很难理解您要实现的目标。 预期输出是否更清楚?我完全知道这段代码无效,但应该证明目标。 【参考方案1】:Elixir/Erlang 不支持模式匹配列表中未知位置的项目,因此您提到的 4 种情况都不能通过模式匹配完成。
唯一可以简化的是您想要列表的第 4 个元素。而不是:
[_ | [_ | [_ | [x | _]]]]
您可以使用该模式:
[_, _, _, x | _]
iex(1)> [_, _, _, x | _] = [1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
iex(2)> x
4
【讨论】:
【参考方案2】:您正在滥用 Elixir 中已知的模式匹配。当您有兴趣在列表中查找值时,没有模式。
——(后面的值)3 = x
iex> [_, x | _] = Enum.drop_while([1,2,3,4,5,6,7], fn e -> e != 3 end)
#⇒ x = 4
——(6之前的值)=x
iex> [x | _] = [1,2,3,4,5,6,7]
...> |> Enum.take_while(fn e -> e != 6 end)
...> |> Enum.reverse
#⇒ x = 5
—(3 到 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]
—(4后3个值的子列表)= [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
.
【讨论】:
我不会称之为滥用模式匹配本身。模式匹配的思想并不局限于固定位置模式。以上是关于Elixir 列表模式匹配 ~ 在使用列表模式匹配常量后得到 x的主要内容,如果未能解决你的问题,请参考以下文章