Reputation: 377
#light
let a1 = [| (1, 1); (2, 1); (3, 1) |]
let a2 = [| (1, 1); (2, 3); (3, 1) |]
let aa = Array.zip a1 a2
|> Array.filter(fun (x, y) -> x <> y)
I want to write a function to do this: it will return the different tuple from two arrays, but I also want to return the index of the different tuple in the second array and the corresponding tuple in the second array. (My code did not work totally yet!) For my above example, I want to return: 1 and (2, 3) Another example:
let a1 = [| (1, 1); (2, 1); (3, 1); (4, 1) |]
let a2 = [| (1, 1); (2, 3); (3, 1); (4, 2) |]
I want to return: 1 and (2, 3); 3 and (4, 2) If you have any idea, please show me your code. Besides, I am not used to the new place for F#, the format makes me feel difficult to find a good place to post my questions, therefore, I still post my question here.
Upvotes: 0
Views: 1070
Reputation: 40145
let diff (a:(int * int)[]) b =
b
|> Array.mapi (fun i tp -> if a.[i] <> tp then (i, tp) else (-1, tp))
|> Array.filter (fun (x, _) -> x >= 0)
DEMO
> diff a1 a2;;
val it : (int * (int * int)) [] = [|1, (2, 3)); (3, (4, 2))|]
Upvotes: 0
Reputation: 47904
Here's one way to do it:
let diff a b =
let s = Set.ofSeq a
b
|> Seq.mapi (fun i x -> i, x)
|> Seq.filter (fun (_, x) -> not (Set.contains x s))
Example
let a1 = [| (1, 1); (2, 1); (3, 1) |]
let a2 = [| (1, 1); (2, 3); (3, 1) |]
diff a1 a2 //output: seq [(1, (2, 3))]
This works for any collection (list
, array
, seq<_>
, set
, etc) and the sequences may be of different lengths. If you know you'll always be using arrays of equal length, you can optimize accordingly (see desco's answer).
Upvotes: 0
Reputation: 16782
let a1 = [| (1, 1); (2, 1); (3, 1) |]
let a2 = [| (1, 1); (2, 3); (3, 1) |]
let diff =
(a1, a2)
||> Array.mapi2(fun i t1 t2 -> (i, t1, t2))
|> Array.choose(fun (i, a, b) -> if a <> b then Some (i, b) else None)
Upvotes: 4