如何在Haskell中向右或向左移动List的1个元素?

时间:2018-03-27 16:46:52

标签: list haskell

您好我一直在找答案,但找不到答案。假设我们有一个类似[1,10,4,5,3]的列表,如何将5向左移动,以便此列表变为[1,10,5,4,3]

我尝试swapElementsAt找到该元素的索引,但看起来非常不足。

2 个答案:

答案 0 :(得分:1)

swapElementsAt :: Int -> [a] -> [a]                                             
swapElementsAt n list = let (beg, a:b:rest) = splitAt (n-1) list in beg ++ b:a:rest

就像

一样
λ> swapElementsAt 3 [1,10,4,5,3]
[1,10,5,4,3]

答案 1 :(得分:0)

如果您要从左到右遍历输入列表,查看列表开头的非常本地附近(如果您可以轻松地模式匹配的话),请考虑如何编写此函数?

最直接的方法是对前两个元素进行模式匹配,并检查第二个元素是否与您的模式匹配。如果是这样,只需通过交换这些元素并附加列表的其余部分来构建一个新列表,否则,递归遍历其余部分。

在代码中:

swapElem :: Eq a => a -> [a] -> [a]
swapElem e (x:y:xs) | y == e = y : x : xs
swapElem e (x:xs) = x : swapElem e xs
swapElem _ [] = []

第一个模式仅在列表中至少有两个元素时匹配,第二个元素等于所需的元素。如果元素较少或第二个元素不正确,则它将落入第二个模式,匹配任意非空列表并在列表的其余部分调用swapElem。第三种模式是提供空输入列表的基本递归情况。

请注意,此代码仅更改目标元素的第一次出现:

Prelude> swapElem 5 [1, 10, 4, 5, 3]
[1,10,5,4,3]
Prelude> swapElem 5 [1, 10, 5, 4, 5, 3]
[1,5,10,4,5,3]

你如何改变它以便左移所有5

此外,答案取决于您的输入究竟是什么。 @Scarabyte的答案考虑了你给出目标元素位置的情况,而这种方法则考虑了你想要向左移动的元素。