Shiro Pie
Shiro Pie

Reputation: 223

F# filtering list

How would I filter out a list by the index ? List: [400; 5; 401; 6; 403; 7] Filtered List: [5; 6; 7;]

I want to filter out the odd index numbers. So I could compare the values and then print out the largest value.

Upvotes: 5

Views: 2608

Answers (3)

David Raab
David Raab

Reputation: 4488

Here is another solution using foldBack

let folder x (index,lst) =
    if   index % 2 = 0
    then (index+1, x::lst)
    else (index+1, lst)

let list = snd (List.foldBack folder [400; 5; 401; 6; 403; 7] (0,[]))

Upvotes: 1

rmunn
rmunn

Reputation: 36678

In the specific case you asked about (keeping the odd index numbers and dropping the even ones), John Reynolds' answer will work. But in the general case where your index-based filter is more complicated, you'd want to use Seq.indexed, which turns any list of items into a list of (index, item) pairs. E.g.:

["apple"; "banana"; "cherry"] |> Seq.indexed |> List.ofSeq
// Produces [(0, "apple"); (1, "banana"); (2, "cherry")]

With this approach, you would then use Seq.filter to do the filtering you want, then turn the sequence back into a list at the end:

let keepOdd (idx, item) =
    // A more complicated filter might use the item parameter too
    idx % 2 <> 0

let input = [400; 5; 401; 6; 403; 7]
input |> Seq.indexed |> Seq.filter keepOdd |> List.ofSeq

Upvotes: 4

John Reynolds
John Reynolds

Reputation: 5057

A simple and straight forward approach would be to recurse through the list and pick every second element:

let getOddIndexed list =
    let rec aux acc xs =
        match xs with
        | _::x::tail -> aux (x::acc) tail
        | _ -> acc |> List.rev
    aux [] list

Upvotes: 5

Related Questions