Unique values of array in swift

IosSwift

Ios Problem Overview


I'm building an iOS app with swift and i need to get all unique values of array of strings.

I've been reading the apple developer docs but it doesn't seem to have a function for it.

Can someone give me an hint?

Ios Solutions


Solution 1 - Ios

There might be a more efficient way, but an extension would probably be most straightforward:

extension Array where Element: Equatable {
    var unique: [Element] {
        var uniqueValues: [Element] = []
        forEach { item in
            guard !uniqueValues.contains(item) else { return }
            uniqueValues.append(item)
        }
        return uniqueValues
    }
}

If order doesn't matter and objects are also hashable:

let array = ["one", "one", "two", "two", "three", "three"]
// order NOT guaranteed
let unique = Array(Set(array))
// ["three", "one", "two"]

Solution 2 - Ios

There isn't a function to do this in the Swift standard library, but you could write one:

extension Sequence where Iterator.Element: Hashable {
    func unique() -> [Iterator.Element] {
        var seen: [Iterator.Element: Bool] = [:]
        return self.filter { seen.updateValue(true, forKey: $0) == nil }
    }
}

let a = ["four","one", "two", "one", "three","four", "four"]
a.unique // ["four", "one", "two", "three"]

This has the downside of requiring the contents of the sequence to be hashable, not just equatable, but then again most equatable things are, including strings.

It also preserves the original ordering unlike, say, putting the contents in a dictionary or set and then getting them back out again.

Solution 3 - Ios

I don't know of a built in way. This generic function would do it:

func distinct<S: SequenceType, E: Equatable where E==S.Generator.Element>(source: S) -> [E]
{
	var unique = [E]()
	
	for item in source
	{
		if !contains(unique, item)
		{
			unique.append(item)
		}
	}
	return unique
}

The downside here is that this solution runs in O(n2).

Solution 4 - Ios

Use a dictionary like var unique = [<yourtype>:Bool]() and fill in the values like unique[<array value>] = true in a loop. Now unique.keys has what you need.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3806505View Question on Stackoverflow
Solution 1 - IosLoganView Answer on Stackoverflow
Solution 2 - IosAirspeed VelocityView Answer on Stackoverflow
Solution 3 - IosBen KaneView Answer on Stackoverflow
Solution 4 - Iosqwerty_soView Answer on Stackoverflow