James Webster
James Webster

Reputation: 32066

Is there a Swift one-liner to remove an element from an array if present and append it if not?

This is a construct I come across quite a lot. Is there a nice way to one-line it in Swift?

I could just write an extension on Sequence for it, but I feel like there's a "obvious" higher-order-function / set theory technique that is eluding me.

if array.contains(element) {
    array.removeObject(object: element)
}
else {
    array.append(element)
}

I don't think the solution will even necessarily be nicer per se, it's just something I think about every time I have to write this.

Upvotes: 5

Views: 1501

Answers (3)

Ahmed M. Hassan
Ahmed M. Hassan

Reputation: 1286

Based on the great answer by. James Webster. We can enhance for reusability.

extension Set {
    /// Inserts given element if it doesn't exist in the set or removes it.
    ///
    mutating func withSymmetricDifference(_ element: Element) {
        self = symmetricDifference([element])
    }
}

Usage

var set = Set([1, 2, 3])
set.withSymmetricDifference(1) // [1, 2, 3]
set.withSymmetricDifference(1) // [2, 3]

Upvotes: 1

James Webster
James Webster

Reputation: 32066

I've found the part of Set Theory that was eluding me! The result I want is the Symmetric Difference of the two arrays and this is included in Swift's set:

var element = Set([1])
var set = Set([1, 2, 3])

set = set.symmetricDifference(element) //2, 3
set = set.symmetricDifference(element) //1, 2, 3

Upvotes: 10

PGDev
PGDev

Reputation: 24341

You can try using Set instead,

var set: Set<Int> = [1, 2, 4]
if !set.insert(4).inserted {
    set.remove(4)
}

Upvotes: 2

Related Questions