Обмен каждой пары элементов в списке F # - PullRequest
3 голосов
/ 19 сентября 2011

Я уверен, что есть лучший способ поменять элементы в списке по парам ([1; 2; 3; 4] -> [2; 1; 4; 3]), так как я делаю слишком много добавляется по моему вкусу, но я не уверен, как лучше это сделать.

let swapItems lst =
    let f acc item =
        match acc with
        | [] -> [item]
        | hd :: next :: tl when tl <> [] -> [next] @ tl @ [item;hd]
        | _ -> item :: acc
    List.fold f [] lst

Как я могу улучшить это? Это работает только для списков, имеющих четную длину.

Ответы [ 3 ]

3 голосов
/ 20 сентября 2011

Самое простое из возможных решений:

let rec swapItems = function
  | a::b::xs -> b::a::swapItems xs
  | xs -> xs

Мне нравится делать имена переменных, которые представляют собой последовательности, например списки, во множественном числе, например, xs вместо x.

Примечание.что это не хвостовая рекурсия, поэтому переполнение стека произойдет, если вы укажете очень длинный список.

2 голосов
/ 19 сентября 2011

Что по этому поводу:

let rec swapItems = function
    | []
    | _::[] as l -> l
    | a::b::t ->
        b::a::(swapItems t)

1 голос
/ 19 сентября 2011

Используя функции высшего порядка, это можно сделать так:

let swapItems l =
    l |> List.toSeq |> Seq.pairwise
    |> Seq.mapi (fun i (a,b) -> if i % 2 = 0 then seq [b;a] else Seq.empty)
    |> Seq.concat |> Seq.toList
...