我正在通过Learn You a Haskell阅读并找到了我正试图将列表中的元素移动到头部的位置.我想出了我认为天真的方式,如果有人能告诉我经验丰富的Haskell程序员会做什么,我很好奇.
在这个例子中,我有一个Integers列表,我想将元素'4'(索引'3')移动到列表的头部.
let nums = [1, 2, 3, 4, 5]
(nums !! 3) : delete (nums !! 3) nums
Run Code Online (Sandbox Code Playgroud)
返回[4,1,2,3,5].
你怎么看?
sth*_*sth 15
我会这样做:
move n as = head ts : (hs ++ tail ts)
where (hs, ts) = splitAt n as
Run Code Online (Sandbox Code Playgroud)
splitAt在给定位置拆分列表,它返回由拆分创建的两个部分(此处hs和ts).应该移到前面的元素现在位于开头ts.head ts只返回第一个元素ts,tail ts返回除第一个元素之外的所有元素.函数的结果只是按正确的顺序组合这些部分:hs与tail ts元素连接和前置head ts.
Don*_*art 11
经验丰富的Haskellers几乎没有使用列表索引.我会使用break来避免重复遍历(假设你想匹配元素'4',而不是索引'3'):
case break (== 4) [1, 2, 3, 4, 5] of
(a,x:xs) -> x:a ++ xs
(a,xs) -> a ++ xs
Run Code Online (Sandbox Code Playgroud)
如:
Prelude Data.List> case break (== 4) [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs
[4,1,2,3,5]
Run Code Online (Sandbox Code Playgroud)
我们也可以通过'splitAt'进行索引:
Prelude Data.List> case splitAt 3 [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs
[4,1,2,3,5]
Run Code Online (Sandbox Code Playgroud)
对某些解决方案的小修改:
toHead n xs = x : pre ++ post
where (pre, x:post) = splitAt n xs
Run Code Online (Sandbox Code Playgroud)
使用模式匹配而不是headntail