-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?

Cesare
  • 9,139
  • 16
  • 78
  • 130

3 Answers3

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.

vadian
  • 274,689
  • 30
  • 353
  • 361
2

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

didSet {
    array = Array(Set(array))
    ...
}
Robert Dresler
  • 10,580
  • 2
  • 22
  • 40
  • You're right, but isn't `didSet` supposed to be called every time the array is assigned to something? – Cesare Dec 25 '18 at 11:40
  • @Cesare you may find this post helpful: https://stackoverflow.com/questions/39819081/in-swift-does-resetting-the-property-inside-didset-trigger-another-didset – Robert Dresler Dec 25 '18 at 12:09
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))
  }
}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
SPatel
  • 4,768
  • 4
  • 32
  • 51