我知道你已经得到了一个答案,但是昨天在去海滩之前我看到了你的问题,当我看着风筝冲浪“芭蕾舞”时,我想到了这个答案,所以我提供给你,它与 Steve 的答案有点不同,可能会更有趣。
在这种情况下,无法使用 lists:map 函数进行分析,因为它仅将给定函数应用于列表的每个元素以构建具有相同长度的新列表。无法构建嵌套列表。正如 @Steve 所说,您需要一个累加器来逐步构建结果。
lists 库提供了一种在遍历列表时累积项的函数:lists:foldl/3(也存在 foldr、mapfoldl 和 mapfoldr),在这种情况下,问题在于定义将帮助我们构建预期结果的累加器。
可以适合单个形式中的2个需求的最简单结构是列表的列表:[SublistInProgress|PreviousWork]
现在我们知道了累加器的形式,我们可以定义负责构建它的函数,有3种情况:
- 我们找到了“(”:开始一个新的子列表,并“存储”先前的累加器
- 我们找到了“)”:将子列表添加到先前的累加器中
- 任何其他情况都将元素添加到正在进行的子列表中。
在 shell 中:
1> F = fun("(",Acc)-> [[],Acc];
1> (")",[SubList,[Hacc|Tacc]]) -> [[lists:reverse(SubList)|Hacc]|Tacc];
1> (X,[Hacc|Tacc]) -> [[X|Hacc]|Tacc] end.
#Fun<erl_eval.12.52032458>
注意:我使用构造函数
[X|Hacc]
而不是
Hacc ++ [X]
来累积列表中的元素,这是一个好习惯,因为它避免了在每个步骤中创建完全新的列表(这样做可以避免我的朋友@Hynek-Pichi-Vychodil的评论:o)。因此,当我要存储它时,必须将列表反转。
在函数lists:foldl(F,[[]],L)
中使用F,我们将得到一个元素的列表,该元素是期望结果的反向。因此,我们必须将此调用嵌入特定的函数库中:
2> Transform = fun(L) -> [R] = lists:foldl(F,[[]],L),
2> lists:reverse(R) end.
我们可以进行测试:
3> L1 = ["0", "(", "1", "2", "3", ")"].
["0","(","1","2","3",")"]
4> L2 = ["0", "(", "11", "22", "(", "333", "444","(", "5555", ")", "666", ")", "77", "88", ")", "9"].
["0","(","11","22","(","333","444","(","5555",")","666",")",
"77","88",")","9"]
5> Transform(L1).
["0",["1","2","3"]]
6> Transform(L2).
["0",["11","22",["333","444",["5555"],"666"],"77","88"],"9"]