Unique Values of Array in Swift

Find unique values in a Swift Array

You can use NSCountedSet

let text = "Silent Night Holy Night"
let words = text.lowercased().components(separatedBy: " ")
let countedSet = NSCountedSet(array: words)
let singleOccurrencies = countedSet.filter { countedSet.count(for: $0) == 1 }.flatMap { $0 as? String }

Now singleOccurrencies contains ["holy", "silent"]

Counting unique items in array. (Swift)

You can use NSSet to throw away duplicates:

let array:Array = [1,3,2,4,6,1,3,2]
let count = NSSet(array: array).count
println(count)

This prints:

5

get distinct elements in an array by object property

Hope this will help you:

class Item:Equatable, Hashable {
var name: String
init(name: String) {
self.name = name
}
var hashValue: Int{
return name.hashValue
}

}

func ==(lhs: Item, rhs: Item) -> Bool {
return lhs.name == rhs.name
}


let items = [Item(name:"1"), Item(name:"2"), Item(name:"1"), Item(name:"1"),Item(name:"3"), Item(name:"4")]

var uniqueArray = Array(Set(items))

Append unique values to an array in swift

You can use a Set which guarantees unique values.

var selectedValues = Set()
// ...
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") }

How to get distinct values from an Array of Classes?

Set requires your elements to be Hashable. That means they have to be Equatable and provide a hashing value.

If your aim is to create list of unique categories, then you should start by creating an array of categories:

let categories = (self.items ?? []).compactMap { $0.category }

Then you can simply get unique categories using Set:

let uniqueCategories = Array(Set(categories))

However, note that Set does not keep items ordered. If you also need to keep the categories in order then I would recommend a simple Array extension:

extension Array where Element: Hashable {
func distinct() -> Array {
var set = Set()
return filter {
guard !set.contains($0) else { return false }
set.insert($0)
return true
}
}
}

or simplified using Set.insert return value (Leo Dabus's idea):

extension Array where Element: Hashable {
func distinct() -> Array {
var set = Set()
return filter { set.insert($0).inserted }
}
}

and then

let uniqueCategories = (self.items ?? [])
.flatMap { $0.category }
.distinct()

How to display unique elements of an array using Swift?

If you don't care about order:

Simply use a set:

let set: Set = ["a", "s", "d", "s", "f", "g" , "g", "h", "e"]
print(set) // ["a", "s", "f", "g", "e", "d", "h"]

If you care about the order:

Use this extension, which allows you to remove duplicate elements of any Sequence, while preserving order:

extension Sequence where Iterator.Element: Hashable {
func unique() -> [Iterator.Element] {
var alreadyAdded = Set()
return self.filter { alreadyAdded.insert($0).inserted }
}
}

let array = ["a", "s", "d", "s", "f", "g" , "g", "h", "e"]
let result = array.unique()
print(result) // ["a", "s", "d", "f", "g", "h", "e"]

Removing duplicate elements from an array in Swift

You can roll your own, e.g. like this:

func unique(source: S) -> [T] where S.Iterator.Element == T {
var buffer = [T]()
var added = Set()
for elem in source {
if !added.contains(elem) {
buffer.append(elem)
added.insert(elem)
}
}
return buffer
}

let vals = [1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]
let uniqueVals = uniq(vals) // [1, 4, 2, 6, 24, 15, 60]

And as an extension for Array:

extension Array where Element: Hashable {
func uniqued() -> Array {
var buffer = Array()
var added = Set()
for elem in self {
if !added.contains(elem) {
buffer.append(elem)
added.insert(elem)
}
}
return buffer
}
}

Or more elegantly (Swift 4/5):

extension Sequence where Element: Hashable {
func uniqued() -> [Element] {
var set = Set()
return filter { set.insert($0).inserted }
}
}

Which would be used:

[1,2,4,2,1].uniqued()  // => [1,2,4]

getting unique items in an array

let uniqueList = nationalities.reduce([], {
$0.contains($1) ? $0 : $0 + [$1]
})

Unique array of objects

You need to add this extension to return an ordered set from your people array.

extension Collection where Element: Hashable {
var orderedSet: [Element] {
var set: Set = []
return reduce(into: []){ set.insert($1).inserted ? $0.append($1) : () }
}
}

You will also have to make your Person class Equatable:

func ==(lhs: Person, rhs: Person) -> Bool {
return lhs.id == rhs.id
}

class Person: Equatable {
let id: String
let name: String
init(id: String, name: String) {
self.id = id
self.name = name
}
}

Testing

let person1 = Person(id: "1", name: "Adam") 
let person2 = Person(id: "1", name: "Adam")
let person3 = Person(id: "2", name: "John")
let person4 = Person(id: "2", name: "John")
let person5 = Person(id: "3", name: "Michael")
let person6 = Person(id: "4", name: "Nick")
let person7 = Person(id: "5", name: "Tony")
let people = [person1,person2,person3,person4,person5,person6,person7]
people.orderedSet //[{id "1", name "Adam"}, {id "2", name "John"}, {id "3", name "Michael"}, {id "4", name "Nick"}, {id "5", name "Tony"}]


Related Topics



Leave a reply



Submit