Skip to content

Instantly share code, notes, and snippets.

@devshorts
Created August 31, 2013 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devshorts/6399857 to your computer and use it in GitHub Desktop.
Save devshorts/6399857 to your computer and use it in GitHub Desktop.
Find a subset of a sequence or an array in F# given a source collection and a target collection
module x
let list = [-1;0;1;2;3;4;5;6;7;8;9] |> List.toArray
let target = [1;2;3] |> List.toArray
let nope = [4;1;2] |> List.toArray
/// <summary>
/// Sequenes are basically IEnumerable, so you can't do structural equality on them
/// this is why they are converted to an F# list before doing comparison, otherwise
/// their references are compared
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
let rec seqHasSubset source target =
let eq seq1 seq2 = (seq1 |> Seq.toList) = (seq2 |> Seq.toList)
match Seq.length source with
| x when x < Seq.length target -> false
| _ when Seq.take (Seq.length target) source |> eq <| target -> true
| _ -> seqHasSubset (Seq.skip 1 source) target
/// <summary>
/// Arrays however, have structural equality AND support array slicing
/// (which lists and sequences do not). If you have an array you can do something
/// like this
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
let rec arrayHasSubset (source:'a []) (target : 'a [])=
match source.Length with
| x when x < target.Length -> false
| _ when source.[0..target.Length - 1] = target -> true
| _ -> arrayHasSubset source.[1..] target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment