solarenqu
solarenqu

Reputation: 814

How to compare two "generic" array in swift

I have two arrays:

var tstFrames = [TimeFrame]()
var tstFramesRefresh = [TimeFrame]()

Does anybody know how to compare them?

I found some examples adding array to Set, but Set doesn't have initializer which can accept this arraytype.. :(

The two array has almost the same instances of TimeFrame object but tstFramesRefresh has one more which is not in tstFrames array i would get that one TimeFrame object.

Upvotes: 0

Views: 593

Answers (1)

Airspeed Velocity
Airspeed Velocity

Reputation: 40955

When you say “compare” – do you mean equal, lexicographic comparison, or diff? Sounds like you want a diff.

The set solution might look like this (assuming you want things in one not in the other, rather than the disjunction of the two):

let a = [1,2,3]
let b = [1,2]

Set(a).subtract(b)  // returns a set of {3}

Presumably your issue is that TimeFrame is not Hashable, hence it won’t work inside a set.

You could instead use contains to check if each element of a were a member of b. Unfortunately this will be quite inefficient for large sets, since contains works in linear time so complexity will be O(n^2). But it’s easy to do:

func subtract<S: SequenceType, C: CollectionType, T: Equatable
    where C.Generator.Element == T, S.Generator.Element == T>
    (source: S, toSubtract: C) -> [S.Generator.Element] {
        return filter(source) { !contains(toSubtract, $0) }
}


subtract(a, b)  // returns [3]

More efficient solutions if your object were Comparable could use sorting or a tree structure.

If your objects aren’t Equatable either, you’d need a version that took a closure to check for equivalence:

func subtract<S: SequenceType, C: CollectionType>
    (source: S, toSubtract: C,
     isEquivalent: (S.Generator.Element, C.Generator.Element) -> Bool)
    -> [S.Generator.Element] {
        let x = filter(source) { elem in
            return !contains(toSubtract) { isEquivalent(elem,$0) }
        }
        return x
}

subtract(a, b) { $0 == $1 }

If you just want to check if they are equal, then == will do it – unless the objects aren’t equatable, in which case use the equal function that takes a comparator function:

// asuming these are classes and reference equality is reasonable thing to check
equal(tstFrames, tstFramesRefresh) { $0 === $1 } 

Upvotes: 4

Related Questions