получение различных элементов в массиве по свойству объекта
У меня есть массив объектов. Я хочу получить различные элементы в этом массиве путем сравнения объектов на основе его свойства name
class Item {
var name: String
init(name: String) {
self.name = name
}
}
let items = [Item(name:"1"), Item(name:"2"), Item(name:"1"), Item(name:"1"),Item(name:"3"), Item(name:"4")]
Результат:
let items = [Item(name:"1"), Item(name:"2"),Item(name:"3"), Item(name:"4")]
Как я могу сделать это в swift?
3 ответа:
Надеюсь, это поможет вам:
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))
Вот расширение массива, возвращающее уникальный список объектов, основанный на заданном ключе:
extension Array { func unique<T:Hashable>(by: ((Element) -> (T))) -> [Element] { var set = Set<T>() //the unique list kept in a Set for fast retrieval var arrayOrdered = [Element]() //keeping the unique list of elements but ordered for value in self { if !set.contains(by(value)) { set.insert(by(value)) arrayOrdered.append(value) } } return arrayOrdered } }
Для вашего примера вы можете сделать:
let uniqueBasedOnName = items.unique{$0.name}
В Swift можно использовать протокол Equatable, чтобы отличить уникальный элемент в массив объекта.
struct Item:Equatable{ var name:String var price:Double init(name:String,price:Double) { self.name = name self.price = price } static func ==(lhs: Item, rhs: Item) -> Bool{ return lhs.name == rhs.name } } class ViewController: UIViewController { var books = [Item]() override func viewDidLoad() { super.viewDidLoad() items.append(Item(name: "Example 1", price: 250.0)) items.append(Item(name: "Example 2", price: 150.0)) items.append(Item(name: "Example 1", price: 150.0)) items.append(Item(name: "Example 1", price: 150.0)) items.append(Item(name: "Example 3", price: 100.0)) items.unique().forEach { (item) in print(item.name) } } } extension Sequence where Iterator.Element: Equatable { func unique() -> [Iterator.Element] { return reduce([], { collection, element in collection.contains(element) ? collection : collection + [element] }) } }