19

I haven't found anything on that in Swift. Have found how to find unique values on an array, but not this. Sorry if it sounds quite basic...

But I have the following array

var selectedValues = [String]()

And the following value that comes from a Parse query

 var objectToAppend = object.objectForKey("description")! as! String

this is how I'am doing it at the moment.

self.selectedHobbies.append(objectToAppend)

But because the query happens repeated times, it ends up appending repeated values. It works, but I just want to not waste memory and only keep unique values.

Any ideas on how to solve that in swift?

GuiSoySauce
  • 1,763
  • 3
  • 24
  • 37

2 Answers2

33

You can use a Set which guarantees unique values.

var selectedValues = Set<String>()
// ...
selectedValues.insert(newString) // will do nothing if value exists

Of course, the elements of a Set are not ordered.

If you want to keep the order, just continue with the Array but check before you insert.

if !selectedValues.contains("Bar") { selectedValues.append("Bar") }
Mundi
  • 79,884
  • 17
  • 117
  • 140
  • is it possible to maintain your code syntax but use a `[String]` instead of a `Set`? A `Set` do not have much use for me as I can convert it to a `[String]`. I tried much haven't got much luck with it. – GuiSoySauce Aug 20 '15 at 03:45
  • @Mundi You don't need to do a `contains` check. If you `insert` and the element already exists, nothing will happen. – Alexander Feb 28 '17 at 21:10
  • @Alexander Agree. Changed it. – Mundi Mar 10 '17 at 06:24
  • You can also ignore what you put into the array and just use .unique when you need only the unique values. In some cases this might be preferable, like if the unique check is costly and saving the data isn't. – kevin Feb 12 '18 at 13:59
  • `Set` works with `Hashable` types only. So for example `Set` works but `Set` doesn't – Gargo Mar 21 '23 at 09:03
9

I guess that your problem was resolved but I add my answer for next developers who's facing same problem :)

My solution is to write an extension of Array to add elements from an array with a distinct way:

here the code :

extension Array{
    public mutating func appendDistinct<S>(contentsOf newElements: S, where condition:@escaping (Element, Element) -> Bool) where S : Sequence, Element == S.Element {
      newElements.forEach { (item) in
        if !(self.contains(where: { (selfItem) -> Bool in
            return !condition(selfItem, item)
        })) {
            self.append(item)
        }
    }
  }
}

example:

var accounts: [Account]
let arrayToAppend: [Account]
accounts.appendDistinct(contentsOf: arrayToAppend, where: { (account1, account2) -> Bool in
        return account1.number != account2.number
})