简体   繁体   中英

Haskell function to swap every second element in a list

I'd like to know how to swap every second element of a list in Haskell.

Example output should look like this:

swap [1,2,3,4,5]  
[2,1,4,3,5]

What I have so far is

swap :: [a] -> [a]  
swap [] = []  
swap (x:xs) = head xs : [x]

but this only swaps the first two elements and any attempt I make to make the function recursive causes errors when I try to load the file that contains the function. How to make it recursive?

You need to grab out 2 elements at a time:

swap [] = []
swap (x:y:rest) = y:x:(swap rest)
swap [x] = [x]

The last line is needed to allow odd-length lists -- it matches a list having length exactly 1, so it doesn't overlap either of the other 2 cases (length 0, and length 2 or more).

In addition to the other quite excellent replies, here is a solution that uses some very handy libraries. First, install split , which provides many very nice ways of splitting up a list. Our strategy for this problem will be to first split your list into chunks of size two, then swap each chunk, then concatenate the result back into a flat list. Here's how the key function works:

Prelude Data.List.Split> chunk 2 [1..11]
[[1,2],[3,4],[5,6],[7,8],[9,10],[11]]

To swap the elements of each chunk, we can simply call reverse . So the final result is:

Prelude Data.List.Split> let swap = concat . map reverse . chunk 2
Prelude Data.List.Split> swap [1..5]
[2,1,4,3,5]

@j_random_hacker's solution is better, however, if you want to see your implementation to completion, you could try this:

swap [] = []
swap (x:[]) = [x]
swap (x:xs) = head xs : x : (swap $ tail xs)

Notice however, the use of head and tail are unnecessary, and pattern matching can make things much cleaner here.

import Data.Function(on)

swap = map snd . concatMap reverse . groupBy ((==) `on` fst) . zip (cycle "aabb")

Don't take my solution too serious, I'm just trying to improve my Haskell-Foo...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM