Ocaml 什么';在列表中的任何位置对特定元素进行模式匹配的最佳方法是什么?

Ocaml 什么';在列表中的任何位置对特定元素进行模式匹配的最佳方法是什么?,ocaml,Ocaml,假设我有一些清单 [“a”;“b”;“d”] [“a”;“c”;“d”] 这些元素可以是任意顺序。列表将包含一个“b”或“c”,但决不能同时包含两个 如果列表中有“b”,我想返回一个特定值;如果列表中有“c”,我想返回一个不同的值 我是OCaml新手,但据我所知,通过模式匹配这是不可能的,或者我错过了什么 做这件事最惯用的方法是什么?如果我理解正确,会给您一个未知列表,您知道该列表包含“b”或“c”,但不是两者都包含,您需要确定是哪一种情况。甚至可能找到第一次发生的位置 这是一个有趣的问题。首先

假设我有一些清单

[“a”;“b”;“d”]
[“a”;“c”;“d”]

这些元素可以是任意顺序。列表将包含一个
“b”
“c”
,但决不能同时包含两个

如果列表中有
“b”
,我想返回一个特定值;如果列表中有
“c”
,我想返回一个不同的值

我是OCaml新手,但据我所知,通过模式匹配这是不可能的,或者我错过了什么


做这件事最惯用的方法是什么?

如果我理解正确,会给您一个未知列表,您知道该列表包含
“b”
“c”
,但不是两者都包含,您需要确定是哪一种情况。甚至可能找到第一次发生的位置

这是一个有趣的问题。首先,您当然可以手动编写循环:

让rec查找_b_或_c i=函数
|[]->未找到加薪(*假设不发生?*)的情况
|((“b”|“c”)作为x):::->(i,x)
|_u::xs->find_b_或_c(i+1)xs
在里面
让(i,x)=在
(*…对索引和/或字母进行处理
(例如,测试x=“b”)…*)
然后问题是,是否可以通过组合现有函数来更简洁/优雅地编写它。如果您对索引不感兴趣,只需使用
List.find
或其变体返回一个选项:

让x=List.find(fun x->x=“b”| x=“c”)我的列表在(*…*)
您还可以使用
List.mem
(或者更一般地说是
List.exists
)测试
“b”的成员资格;但是,使用这种方法,只要列表中包含
“c”
(对于一个非常长的列表,它的开头有
“c”
,但没有
“b”
,搜索就不会出现短路,这将浪费大量时间)


但是,无法使用获取索引,因为它们都不返回索引。这是故意的,因为列表索引速度很慢(线性时间),您不应该这样做。如果你真的想要索引,你必须使用上面的手动递归,或者写一个更通用的函数
find\u with_index

如果我理解正确,你会得到一个未知列表,你知道它包含
“b”
“c”
,但不是两者都包含,你想确定是哪种情况。甚至可能找到第一次发生的位置

这是一个有趣的问题。首先,您当然可以手动编写循环:

让rec查找_b_或_c i=函数
|[]->未找到加薪(*假设不发生?*)的情况
|((“b”|“c”)作为x):::->(i,x)
|_u::xs->find_b_或_c(i+1)xs
在里面
让(i,x)=在
(*…对索引和/或字母进行处理
(例如,测试x=“b”)…*)
然后问题是,是否可以通过组合现有函数来更简洁/优雅地编写它。如果您对索引不感兴趣,只需使用
List.find
或其变体返回一个选项:

让x=List.find(fun x->x=“b”| x=“c”)我的列表在(*…*)
您还可以使用
List.mem
(或者更一般地说是
List.exists
)测试
“b”的成员资格;但是,使用这种方法,只要列表中包含
“c”
(对于一个非常长的列表,它的开头有
“c”
,但没有
“b”
,搜索就不会出现短路,这将浪费大量时间)


但是,无法使用获取索引,因为它们都不返回索引。这是故意的,因为列表索引速度很慢(线性时间),您不应该这样做。如果你真的想要索引,你必须使用上面的手动递归,或者写一个更通用的函数
find_with_index

,只是为了弄清楚,你的列表有任意长度吗?对于我现在正在做的事情,它们的长度总是=3,但是我试图避免写出所有可能的模式匹配。你不清楚你想测试哪种情况。如果要测试列表是否包含
“c”
,可以使用
list.mem“c”list
。它看起来更像是一个
if
语句的东西,而不是一个模式匹配的东西,就像你说的。啊,对不起,我错误地删除了部分问题。是的,我用Python就是这样做的。。。我只是想知道是否有一种不太必要的方法如果你所有的列表长度最多为3,那么就没有太多的模式可以写了<代码>(将我的_列表与“b”匹配:| |::“b”:| |::|:::“b”:-|->真|->假)
。但是对于如此小的长度,你也可以像Jeffrey所说的那样使用
List.mem
(请参阅我的答案,了解为什么这对于较长的列表来说并不理想)。只是要明确一点,你的列表有任意长度吗?对于我现在正在做的事情,它们的长度总是=3,但是我试图避免写出所有可能的模式匹配。你不清楚你想测试哪种情况。如果要测试列表是否包含
“c”
,可以使用
list.mem“c”list
。它看起来更像是一个
if
语句的东西,而不是一个模式匹配的东西,就像你说的。啊,对不起,我错误地删除了部分问题。是的,我用Python就是这样做的。。。我只是想知道是否有一种不太必要的方法如果你所有的列表长度最多为3,那么就没有太多的模式可以写了<代码>(将我的_列表与“b”匹配:| |::“b”:| |::|:::“b”:-|->真|->假)
。但是对于如此小的长度,您可以像Jeffrey所说的那样使用
List.mem
(请参阅我的答案,了解为什么对于较长的列表,这并不理想)。