首页 > 解决方案 > 枚举过滤:在索引 + 1 处包含值

问题描述

我正在尝试从args列表中解析 unix 样式的标志,即:

args = ["hello", "-f", "val", "-u", "valtwo"]
# Desired outcome: [{"-f", "val"}, {"-u", "valtwo"}]

我已经设法使用以下正则表达式提取标志:

args
|> Enum.filter(fn arg -> Regex.match?(~r/^-{1,2}\w+/, arg) end)
# ["-f", "-u"]

但是,为了获取与这些键对应的,我需要在下一个索引处获取 args 的值。

我考虑过使用Enum.chunk_every(2)(丢弃第一个元素"hello")来转换数组,但这不够灵活,因为这会破坏以下内容:

["hello", "-f", "val", "secondvalforf", "-u", "valtwo"]
# Achieved outcome: [{"-f", "val"}, {"secondvalforf", "-u"}, {"valtwo"}]

任何想法都非常感谢。

标签: listelixir

解决方案


Enum.reduce/3是你的朋友吗?

args = ~w|hello -f val foo -u valtwo|
#⇒ ["hello", "-f", "val", "foo", "-u", "valtwo"]

Enum.reduce(args, [], fn 
  <<?-, _>> = key, args -> [{key, []} | args]
  _, [] -> [] # skip plain arguments
  arg, [{key, last} | rest] -> [{key, last ++ [arg]} | rest]
end)
#⇒ [{"-u", ["valtwo"]}, {"-f", ["val", "foo"]}]

调用Enum.reverse/1结果以保留键的顺序(reduce 新元素添加到累加器以避免在以后创建许多后续链表。)


推荐阅读