1

I'm trying to write an extension to Array that appends an element to the Array only if the element does not exists in the Array already.

This is my code:

extension MutableCollection where Iterator.Element: Equatable {
    mutating func addObjectIfNew <T: Equatable> (_ item: T)  {
        if !self.contains(item as! Self.Iterator.Element) { 
            self.append(x as! Self.Iterator.Element) // offending line
        }
    }
}

I get this error:

error: value of type 'Self' has no member 'append'

What's the proper way to write such extension?

Update: I can't use a Set because I need to perform this operation on an object that needs to be indexed (i.e., Array)

7
  • append doesn't exist on MutableCollection because not all mutable collections support arbitrary sizes like Array does. Make this as an extension on Array.
    – Alexander
    Commented Nov 25, 2016 at 2:42
  • Also, be careful with this, it's a linear time operation. If you're doing it a lot, it's better to use a set.
    – Alexander
    Commented Nov 25, 2016 at 2:43
  • 2
    You are already constraining the collection type to equatable, so there is no need to use T: Equatable at your method
    – Leo Dabus
    Commented Nov 25, 2016 at 3:07
  • 3
    Sets do what you want "out of the box". If you need an ordered collection you can use an NSOrderedSet (which I guess is called an OrderedSet in Swift 3)
    – Duncan C
    Commented Nov 25, 2016 at 3:08
  • 1
    @LeoDabus This works! Can you please add it as an answer so that I can mark it as the correct answer?
    – RawMean
    Commented Nov 25, 2016 at 3:26

1 Answer 1

4

You are already constraining the collection elements to equatable, so there is no need to create a new generic equatable type at your method:

extension RangeReplaceableCollection where Element: Equatable {
    mutating func appendIfNotContains(_ element: Element)  {
        if !contains(element) { append(element) }
    }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.