Check if a list and array are equal F#

Viewed 258

I am trying to compare a list and an array and see if they are equal. Lets say we have a list list = [1;2;3;4] and an array ar = [|1;2;3;4|]. The function should return true if equal and false if not equal. I did it like this:

let list = [1;2;3;4]
let ar = [|1;2;3;4|]

let list' = Array.toList ar
(list = list')

So basically what I am doing is simply convert and compare two lists.. My question is is there any other way to do this, I mean which do not simply convert between list and array and which do not rely entirely on library functions.

5 Answers

You can use the fact that both lists and arrays (as well as most other collections) implement the seq<'a> interface (IEnumerable<T> in the .NET terms) and so you can just pass them to the functions from the Seq module without any conversions. This is just using an interface, so there is no overhead.

The easiest function I can think of for checking whether two sequences are the same is forall2, which takes two sequences and checks that a predicate holds for the elements pairwise. In this case, the predicate is just equality test (fun a b -> a = b) which you can abberviate as (=):

let list = [1;2;3;4]
let ar = [|1;2;3;4|]

Seq.forall2 (=) list ar

There are lots of ways you could do this. Here's one that compares the elements pairwise:

if list.Length = ar.Length then
    Seq.zip list ar
        |> Seq.forall (fun (a, b) -> a = b)
else false

F# docs say:

You compare two sequences by using the Seq.compareWith function. The function compares successive elements in turn, and stops when it encounters the first unequal pair. Any additional elements do not contribute to the comparison.

Which in your case becomes oneliner:

0 = Seq.compareWith (Comparer<_>.Default) list ar

Didn't check if it compiles. Use the Comparer.Default to compare primitives, otherwise, for complex custom types you may need to provide your own.

With Linq;

Enumerable.SequenceEqual (list, ar)

Based on this

let l = [1;2;3;4]
let a = [|1;2;3;4|]
let result = Seq.compareWith Operators.compare l a
Related