让
lst
成为一个包含元组的列表,我想反转每个元组(元组的顺序需要相同)。例如:
[(a,b);(c,d)] -> [(b,a);(d,c)]
我知道可以用地图来完成:
List.map (fun (a,b) -> (b,a)) [(1,2);(3,4)];;
- : (int * int) list = [(2, 1); (4, 3)]
但我正在寻找一种方法来实现它
List.fold_left
。我的方法是将列表与 []
作为累加器进行匹配,将每个反向元组连接在一起,但我不断收到类型错误:
List.fold_left (fun (a,b) -> (b,a)) [] lst;;
List.fold_left
采用三个参数:
'a -> 'b -> 'a
'a
'b list
您的函数
(fun (a,b) -> (b,a))
缺少一个参数,即累加器,您想要在其上连接反转对
(fun acc (a,b) -> (b,a) :: acc)
使用
List.map
似乎是一个自然的选择,因为你可以这样做:
List.map (fun (a, b) -> (b, a)) lst
但是如果你想使用
List.fold_left
那么你需要反转每对,然后将其添加到累加器列表中:
List.fold_left (fun acc (a, b) -> (b, a)::acc) [] lst
由于 Fold_left 采用以下函数签名:
('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
,因此您需要确保您的第一个参数是一个接受累加器列表和单个列表元素(在本例中为元组)的函数,然后返回一个列表。
编辑:@Chris 正确地指出,通过这个解决方案,元组本身的顺序也会翻转。您可以通过用
List.rev
包装函数来解决此问题,或者您可以将元组附加到列表的末尾,而不是使用 cons-ing:
List.fold_left (fun acc (a, b) -> acc@[(b, a)]) [] lst
@Lhooq 和 @rithvik 的答案大多都是正确的,但会颠倒结果列表中元组的顺序。
我们需要将结果提供给
List.rev
或使用List.fold_right
。
# List.fold_left (fun acc (a, b) -> (b, a) :: acc) [] [(1, 2); (3, 4)]
|> List.rev;;
- : (int * int) list = [(2, 1); (4, 3)]
# List.fold_right (fun (a, b) acc -> (b, a) :: acc) [(1, 2); (3, 4)] [];;
- : (int * int) list = [(2, 1); (4, 3)]