F # Cutting the list in half using functional programming

I try to inject a list into a function, and it sends me a list with the first half of the elements taken by f # with the recursion below, but I continue to run into a problem of the base case, which I just cannot understand. Any suggestions? I use the second shadow list to calculate how far I need to go until I go to the list (by deleting two items at a time)

let rec dropHalf listToDrop shadowList = 
    match shadowList with
    | [] -> listToDrop
    | shadowHead2::shadowHead1::shadowTail -> if shadowTail.Length<=1 then listToDrop else 
                                    match listToDrop with 
                                    |[] -> listToDrop
                                    |listToDropHead::listToDropTail -> dropHalf listToDropTail shadowTail
+3
source share
4 answers
let rec dropHalf listToDrop shadowList = 
    match shadowList with
    | [] -> listToDrop
    | shadowHead2::[] -> listToDrop   (* odd number! *)
    | shadowHead1::shadowHead2::shadowTail -> 
        match listToDrop with 
        | [] -> listToDrop   (* should never happen? *)
        | listToDropHead::listToDropTail -> dropHalf listToDropTail shadowTail

, F #, ocaml, , , , ( , ?!). , , , . , .

, , - " ", , .

+2

, , , :

let dropHalf xs =
    let rec dropHalf' ys zs =
      match ys, zs with
      | _::_::ys', _::zs' -> dropHalf' ys' zs'
      | _, zs' -> zs' (* One half of the shadow list ys *)
    dropHalf' xs xs

, :

let rec drop n xs =
   match xs, n with
   | _ when n < 0 -> failwith "n should be greater or equals to 0"
   | [], _ -> []
   | _, 0 -> xs
   | _::xs', _ -> drop (n-1) xs'

let dropHalf xs =
    xs |> drop (List.length xs/2)

, :

let dropHalf xs = 
    let xa = Array.ofList xs
    xa.[xa.Length/2..] |> List.ofArray
+1

As a rule, if you call Lengthon the list, then most likely the best way to do what you do. Lengthmust iterate over the whole list and therefore O (n).

let secondHalf list =
    let rec half (result : 'a list) = function
        | a::b::sx -> half result.Tail sx
        // uncomment to remove odd value from second half
        // | (a::sx) -> result.Tail 
        | _ -> result

    half list list
+1
source

Here is an example that you described.

open System
open System.Collections.Generic

let items = seq { 1 .. 100 } |> Seq.toList

let getBackOfList ( targetList : int list) = 
    if (targetList.Length = 0) then 
        targetList
    else
        let len = targetList.Length
        let halfLen = len / 2
        targetList |> Seq.skip halfLen |> Seq.toList

let shortList = items |> getBackOfList

("Len: {0}", shortList.Length) |> Console.WriteLine

let result = Console.ReadLine() 

Hope this helps

0
source