如何在Haskell中的列表中移动元素?

afr*_*eve 6 haskell list

我正在通过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在给定位置拆分列表,它返回由拆分创建的两个部分(此处hsts).应该移到前面的元素现在位于开头ts.head ts只返回第一个元素ts,tail ts返回第一个元素之外的所有元素.函数的结果只是按正确的顺序组合这些部分:hstail ts元素连接和前置head ts.

  • toHead nl = let(xs,y:ys)= splitAt in y:xs ++ ys (3认同)

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)


yai*_*chu 8

对某些解决方案的小修改:

toHead n xs = x : pre ++ post
  where (pre, x:post) = splitAt n xs
Run Code Online (Sandbox Code Playgroud)

使用模式匹配而不是headntail