2011-09-18 2 views
3

쌍으로 항목을 서로 바꿀 수있는 좋은 방법이 있다는 것이 긍정적입니다 ([1; 2; 3; 4] -> [2; 1; 4; 3 ]) 내가 좋아하는 것에 너무 많은 덧붙이기를하고 있지만 최선의 방법을 잘 모르겠다.F # 목록의 모든 항목 쌍 바꾸기

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 

어떻게 향상시킬 수 있습니까? 이것은 짝수 길이의 목록에서만 작동합니다.

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

:이 약

답변

2

무엇입니까?

+3

나는이 방법이 약간 더 우아한'function :: a :: b :: t -> b :: a :: t | a -> failwith "충분하지 않은 요소"라고 생각한다. " –

+0

brillant thanks, and curses to F # 항상 간단한 것을 만들기 때문에) # – Dylan

+0

@jpalmer, 왜 그가이 일을하는지 모르겠다.하지만 나는이 솔루션이 홀수 개의 요소 목록에 대해 작동하기를 원했다고 생각했다. –

1

고차 함수를 사용하여이 수행 할 수 있습니다으로 :

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 
+1

목록은 seq이므로''List.toSeq''를 호출 할 필요가 없습니다. 나는 심지어 그것이 (타입 검사기를 강요하는 것 이상의) 무언가를하는지 확신하지 못한다. –

3

간단한 가능한 솔루션 : 나는 "복수"목록과 같은 순서입니다 변수의 이름을 좋아

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

, 예를 들어, x 대신 xs

이것은 꼬리 재귀가 아니므로 매우 긴 목록을 제공하면 오버플로가 스택됩니다.

+1

감사합니다. Jon, 멋진 솔루션이고 읽기가 쉽습니다. – Dylan