2017-02-17 4 views
4

Я провел некоторое исследование, и я вижу, что функция List.zip принимает два списка и возвращает один список кортежей, но как вы меняете один список в список кортежей?F # взять список, вернуть список кортежей

let rec combinePair xs = 
    match xs with 
    | [] -> [] 
    | [x1] -> [] 
    | x1::x2::x3::xs -> [(x1, x2)] 
    | x1::x2::xs -> [(x1, x2)] 

Если нечетное число элементов существует в списке, то последний элемент должен быть отброшен, если четное число элементов существует, они должны быть возвращены в виде списка кортежей. Например

combinePair [x1; x2; x3; x4] = [(x1, x2); (x3, x4)] 

ответ

4

Ваш код почти там.

Вот мышление:

  • когда дается пустой список, то результат будет пустой список (вы уже получили это).
  • При заданном списке одного элемента в результате получается пустой список (полученный тоже).
  • В противном случае первым элементом результата является кортеж, состоящий из первых двух элементов, а остальная часть результата - результат применения одного и того же процесса к остальной части ввода.

Это может быть почти одинаково переведено на F #:

let rec combinePair xs = 
    match xs with 
    | [] | [_] -> [] 
    | x1::x2::rest -> (x1, x2) :: (combinePair rest) 

(обратите внимание, как я объединил два первых случай на одной линии, [] | [_] ->)

+0

Думаю, я до сих пор не понимаю, как работает функциональное программирование. Спасибо за помощь. – jynx678

4

Я уверен, что есть похорошевшие решения, но для тех, у кого есть аллергия на рекурсию:

let xsOdd = [1;2;3;4;5] 

List.chunkBySize 2 xsOdd 
    |> List.filter (fun x -> x.Length = 2) 
    |> List.map (fun x -> x.[0],x.[1]) 
//val it : (int * int) list = [(1, 2); (3, 4)] 
+3

В то время как у нас аллергия ... У меня аллергия на неохраняемую индексацию ;-) Вы могли бы объединить «фильтр» и «карту» в одну, написав «let combPair2 xs = xs |> List.chunkBySize 2 |> List.choose (function | x1 :: x2 :: [] -> Some (x1, x2) | _ -> None) ' –

+0

@AntonSchwaighofer Nice! – s952163

Смежные вопросы