从列表中查找元素并放在前面,同时保留顺序

时间:2016-05-17 16:34:35

标签: haskell

我试图制作一个将颜色列表和特定颜色作为输入的函数。它将查看颜色列表,直到找到特定颜色并将其放在前面。我想在坚持其余数字的顺序的同时做到这一点。

例如:

putfront [] (red:blue:green:yellow:white:pink:orange:[]) yellow

返回

yellow:red:blue:green:white:pink:orange:[]

这是我的尝试:

putfront::[Colour]->[Colour]->Colour-> [Colour]
putfront leftofcurrent (current:rightofcurrent) thecolour
    |current==thecolour = thecolour:leftofcurrent:rightofcurrent
    |otherwise= putfront (leftofcurrent:current:[]) rightofcurrent thecolour

但是Haskell似乎并不满意:

thecolour:leftofcurrent:rightofcurrent

(leftofcurrent:current:[])

话说:

  

预期类型:Pond_Ix         实际类型:[Pond_Ix]

有什么问题?

3 个答案:

答案 0 :(得分:2)

  

但是Haskell似乎并不满意:

thecolour:leftofcurrent:rightofcurrent

那是因为leftofcurrent是一个列表。如果要组合这些列表,则需要:

(thecolour:leftofcurrent) ++ rightofcurrent

同样,(leftofcurrent:current:[])是不可能的,因为leftofcurrent是一个列表,但这可能就是你所追求的:

leftofcurrent ++ [current]

cons运算符:需要左侧的单个元素和右侧的列表。但由于其固定性,您可以将它们链接在一起,以便一堆单个项目由:分隔,并以列表结束。也就是说,

item1:item2:item3:[]
-- is the same as
item1:(item2:(item3:[]))

此外,您的模式匹配并非详尽无遗。您需要处理第二个list参数为空的情况。

putfront leftofcurrent [] thecolour = ...

答案 1 :(得分:1)

我会写如下

putfront :: (Eq a) => a -> [a] -> [a]
putfront a x | a `elem` x = a: filter (not . (==a)) x
             | otherwise = x

> putfront 4 [1..8]
[4,1,2,3,5,6,7,8]

你也可以递归地写它

putfront a x = bubble [] x
         where bubble p [] = p
               bubble p (s:ss) | a==s = a:p++ss
                               | otherwise = bubble (p++[s]) ss
> putfront 3 [1..5]
[3,1,2,4,5]

> putfront 7 [1..5]
[1,2,3,4,5]

答案 2 :(得分:0)

我实际上认为你最好的解决办法是删除项目并将其放在列表的前面,正如你在评论中提到的那样。鉴于你不喜欢这个,我可以建议以下

sortBy (\x y -> case (x, y) of (_, theColour) -> GT; (x, y) ->LT) listOfColours