按对象获取数组中的不同元素 属性
get distinct elements in an array by object property
我有一个对象数组。
我想通过根据其名称 属性
比较对象来获取此数组中的不同元素
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 中执行此操作?
希望对您有所帮助:
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))
这是 return 基于给定键的唯一对象列表的数组扩展:
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{[=11=].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] })
}
}
我使用了@Ciprian Rarau 的甜蜜回答,然后意识到如果元素不是唯一的,我什至不需要首先添加这些元素。所以我为此写了一个小扩展(受答案启发)。
extension Array {
public mutating func appendIfUnique<T: Hashable>(_ newElement: Element, check property: ((Element) -> (T))) {
for element in self {
if property(element) == property(newElement) { return }
}
append(newElement)
}
}
仅在唯一时追加元素:
array.appendIfUnique(newElement, check: { [=11=].name })
使用键路径而不是闭包的解决方案:
extension Sequence {
func uniqued<Type: Hashable>(by keyPath: KeyPath<Element, Type>) -> [Element] {
var set = Set<Type>()
return filter { set.insert([=10=][keyPath: keyPath]).inserted }
}
}
struct Mock { var uuid: UUID; var num: Int }
的示例
let uuid = UUID()
let arr = [
Mock(uuid: uuid, num: 1),
Mock(uuid: uuid, num: 2),
Mock(uuid: UUID(), num: 3)
]
let unique = arr.uniqued(by: \.uuid)
unique
数组将包含第一个 (num = 1) 个和最后一个 (num = 3) 个元素。
我有一个对象数组。 我想通过根据其名称 属性
比较对象来获取此数组中的不同元素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 中执行此操作?
希望对您有所帮助:
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))
这是 return 基于给定键的唯一对象列表的数组扩展:
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{[=11=].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] })
}
}
我使用了@Ciprian Rarau 的甜蜜回答,然后意识到如果元素不是唯一的,我什至不需要首先添加这些元素。所以我为此写了一个小扩展(受答案启发)。
extension Array {
public mutating func appendIfUnique<T: Hashable>(_ newElement: Element, check property: ((Element) -> (T))) {
for element in self {
if property(element) == property(newElement) { return }
}
append(newElement)
}
}
仅在唯一时追加元素:
array.appendIfUnique(newElement, check: { [=11=].name })
使用键路径而不是闭包的解决方案:
extension Sequence {
func uniqued<Type: Hashable>(by keyPath: KeyPath<Element, Type>) -> [Element] {
var set = Set<Type>()
return filter { set.insert([=10=][keyPath: keyPath]).inserted }
}
}
struct Mock { var uuid: UUID; var num: Int }
let uuid = UUID()
let arr = [
Mock(uuid: uuid, num: 1),
Mock(uuid: uuid, num: 2),
Mock(uuid: UUID(), num: 3)
]
let unique = arr.uniqued(by: \.uuid)
unique
数组将包含第一个 (num = 1) 个和最后一个 (num = 3) 个元素。