2014-01-25 5 views
0

Я пытаюсь написать метод, который разбивает список на два. Функция должна возвращать кортеж из двух списков, а аргументы, которые выполняет функция, - это количество элементов в первом списке, а затем список. Вот что я имею в видуРазбиение списка F Sharp

список [1,2,3,4]

сплит (1, список) -> ([1], [2,3,4]) сплит (3, список) -> ([1,2,3], [4])

Вот что я до сих пор:

let rec mysplit = function 
    |(n,[])->([],[]) 
    |(1,x::xs)->(x::[],xs) 
    |(n,x::xs)-> mysplit(n-1,xs) 

Я точно не знаю, как "поймать" кортеж обратно из рекурсивный вызов. Не уверен, где можно добавить дополнительную инструкцию let, чтобы временно сохранить список, который я собираю. Новым для языка, поэтому было бы полезно изучить несколько разных подходов.

ответ

3

Непосредственная реализация будет:

let rec mysplit = function 
    |(n,[])->([],[]) 
    |(1,x::xs)->(x::[],xs) 
    |(n,x::xs)-> let (f, s) = mysplit(n-1,xs) in (x::f, s) 

Вы также можете написать хвостовой рекурсией версии:

let mysplit (n, l) = 
    let rec mysplit' n' (f, s) = function 
    | [] -> (f, s) 
    | (x::xs) as l' -> if n' = 0 then (f, l') else mysplit' (n'-1) (x::f, xs) xs 

    let (f', s) = mysplit' n ([], []) l in (List.rev f', s) 
0

ответ Ли показывает рабочее решение, но ответить на ваш конкретный вопрос, вы могут отображать значения, возвращенные вам в кортеже, например:

let before, after = mysplit (2, [1;2;3;4;5]) 

Вы также может использовать этот трюк для объявления нескольких переменных в одном заявлении:

let i, j, k = (1, 2, 3) 
6

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

let split n l = (l |> Seq.take n, l |> Seq.skip n) 

Что касается возможных крайних случаев, пропустить возвращает пустую последовательность, если есть > n элементов в списке, и принимать будет возвращать первые п элементы, если есть < n элементов в последовательности.

Пробовал в TryFharp.org с вашими примерами, и он работает так, как ожидалось.

+0

Теперь вот что я называю f # – James

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