-2

I created this singleton to access a shared array throughout my app:

class TranslationItems {
    var delegate: TranslationItemsDelegate?

    static let shared = TranslationItems()

    var array = [Translation]() {
        didSet {
            delegate?.newItemAdded()
        }
    }
}

The problem is that this allows for duplication (the array may contain multiple items with the same hashValue). If I check for duplication inside the didSet setter and then change the array there (for example by doing array = Array(Set(array))) that leads to an infinite loop.

How do I remove duplicates in my class?

3

3 Answers 3

3

If you want to avoid duplicates why don't you use a Set anyway (Translation must conform to Hashable)?

var set = Set<Translation>()

However if you want to keep the array a more efficient way is to add an add method which filters the duplicates, Translation must conform to Equatable

func add(object: Translation) {
    if !array.contains(object) {
       array.append(object)
       delegate?.newItemAdded()
    }
}

Making a Set from the Array and then convert it back to Array is unnecessarily expensive.

6
  • array.contains will become expensive for a large number of elements.
    – ielyamani
    Commented Dec 25, 2018 at 11:43
  • 1
    @Carpsen90 Not as expensive as Array(Set(array)) 😉
    – vadian
    Commented Dec 25, 2018 at 11:44
  • 1
    Yes, that's like reaching for your ear with the wrong hand 😜Not sure why such answers are upvoted...
    – ielyamani
    Commented Dec 25, 2018 at 11:49
  • @Carpsen90 Most people especially the newbies are looking for the easiest/shortest solution which is not necessarily the most efficient.
    – vadian
    Commented Dec 25, 2018 at 11:54
  • 1
    [OT] @Cesare Marry is sposare 😉 Buon Natale.
    – vadian
    Commented Dec 25, 2018 at 12:17
2

You can do it exactly how you suggested. This doesn't lead to an infinite loop

didSet {
    array = Array(Set(array))
    ...
}
2
1

Just add one instance method

class TranslationItems {

  var delegate: TranslationItemsDelegate?

  static let shared = TranslationItems()

  private(set) var array = [Translation]() {
      didSet {
          delegate?.newItemAdded()
      }
  } 

  func set(array:[Translation]) {
      self.array = Array(Set(array))
  }
}
0

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