Find unique array of tuples

Tag: collections , f# , duplicates Author: lb7542187 Date: 2011-10-21

I have 4 arrays of different data. For the first array of string, I want to delete the duplicate element and get the results of array of unique tuples with 4 elements.

For example, let's say the arrays are:

let dupA1 = [| "A"; "B"; "C"; "D"; "A" |]

let dupA2 = [| 1; 2; 3; 4; 1 |]

let dupA3 = [| 1.0M; 2.0M; 3.0M; 4.0M; 1.0M |]

let dupA4 = [| 1L; 2L; 3L; 4L; 1L |]

I want the result to be:

let uniqueArray = [| ("A", 1, 1.0M, 1L); ("B", 2, 2.0M, 2L); ("C", 3, 3.0M, 3L); ("D",4, 4.0M, 4L) |]
So you want to zip them together per item? What if arrays contains different number of items?
You checked (V mark) my answer. if you want give to the Ramon's answer, You can change it now.

Best Answer

let zip4 s1 s2 s3 s4 =
  Seq.map2 (fun (a,b)(c,d) ->a,b,c,d) ( s1 s2)( s3 s4)

let uniqueArray = zip4 dupA1 dupA2 dupA3 dupA4 |> Seq.distinct |> Seq.toArray

Other Answer1

You will first need to write a zip4 function which will zip the arrays:

// the function assumes the 4 arrays are of the same length
let zip4 a (b : _ []) (c : _ []) (d : _ []) =
    Array.init (Array.length a) (fun i -> a.[i], b.[i], c.[i], d.[i])

Then a distinct function for arrays, using Seq.distinct:

let distinct s = Seq.distinct s |> Array.ofSeq

And the result would be:

> zip4 dupA1 dupA2 dupA3 dupA4 |> distinct;;
val it : (string * int * decimal * int64) [] =
  [|("A", 1, 1.0M, 1L); ("B", 2, 2.0M, 2L); ("C", 3, 3.0M, 3L);
    ("D", 4, 4.0M, 4L)|]


Thank you very much. Actually, my real problem has 8 arrays of different data type, since I don't know how to write the code like Zip4, as F# has only zip3 at the most; then it is difficult for me to figure out how to find the unique array of tuples.\