我正在寻找一种 shorter/better 方法来从我的核心数据应用程序中获取第一个对象和 NSSet
I'm looking for a shorter/better way to get the first object from and NSSet in my Core Data app
目前我有这个代码:
if let myPhoneNumbers = person.phoneNumbers?.allObjects as? [PhoneNumber] {
for myPhoneNumber in myPhoneNumbers {
mainPhoneNumber = myPhoneNumber.number
break
}
}
这是正确的编码方式吗?我知道 NSSet
是无序的,可能是它没有自己的 .first
实现的原因,例如:
person.phoneNumbers.first
但我认为我的代码不是最优雅的代码,可能不合适 Swift 代码。
我不知道您为什么想要获取集合中的任意 "first" 元素,但您可以:
let first = (person.phoneNumbers?.allObjects as? [PhoneNumber])?.first
这将给出 more/less 个随机结果。以下是我的建议:
- 将 phone 个数字存储在数组中,以便保留用户对 phone 个数字的排序。
- 我认为由用户来确定什么构成主号码会好得多。也许在
Person
. 中存储对 "main" PhoneNumber
对象的引用
在您的代码中,myPhoneNumbers
是一个数组,因此您可以使用 myPhoneNumbers.first
而不是循环。
if let myPhoneNumbers = person.phoneNumbers?.allObjects as? [PhoneNumber] {
mainPhoneNumber = myPhoneNumbers.first
}
但是,正如已经指出的那样,您应该对您的集合强加某种顺序,以便执行此代码的结果对于任何给定的集合都是相同的。武断的结果通常是不好的。
既然你提到你正在使用 Core Data,我建议在你的 Person 实体上添加一个方便的 属性 到 return phone 数字作为排序数组。
如果您的实体看起来像这样...
class PhoneNumber: NSManagedObject {
@NSManaged var number: String
}
class PersonEntity: NSManagedObject {
@NSManaged var phoneNumbers: NSSet?
}
...你可以像这样创造一个便利 属性:
class PersonEntity: NSManagedObject {
@NSManaged var phoneNumbers: NSSet?
// Arrays are often easier to work with than sets,
// so provide a convenience property that returns
// phone numbers sorted
var phoneNumbersArray: [PhoneNumber] {
get {
if let phoneNumbers = phoneNumbers {
return (phoneNumbers.allObjects as! [PhoneNumber]).sorted() {
// here, sorting by phone number, but
// you can sort on whatever you want
.number > [=12=].number
}
}
// return empty array if set is nil
return [PhoneNumber]()
}
}
}
最后,一行代码得到第一个数字,如下所示:
mainPhoneNumber = person.phoneNumbersArray.first
我喜欢将这种类型的便利数组 属性 添加到我的所有具有集合的实体中。在我看来,数组更容易使用。这里我选择return一个空数组而不是一个nil数组,当集合为nil时。如果您可以处理 nil 和空 phone 设置相同,则此方法有效。
另请注意,如果 phoneNumbersArray
为空,则 .first
return 为零。
目前我有这个代码:
if let myPhoneNumbers = person.phoneNumbers?.allObjects as? [PhoneNumber] {
for myPhoneNumber in myPhoneNumbers {
mainPhoneNumber = myPhoneNumber.number
break
}
}
这是正确的编码方式吗?我知道 NSSet
是无序的,可能是它没有自己的 .first
实现的原因,例如:
person.phoneNumbers.first
但我认为我的代码不是最优雅的代码,可能不合适 Swift 代码。
我不知道您为什么想要获取集合中的任意 "first" 元素,但您可以:
let first = (person.phoneNumbers?.allObjects as? [PhoneNumber])?.first
这将给出 more/less 个随机结果。以下是我的建议:
- 将 phone 个数字存储在数组中,以便保留用户对 phone 个数字的排序。
- 我认为由用户来确定什么构成主号码会好得多。也许在
Person
. 中存储对 "main"
PhoneNumber
对象的引用
在您的代码中,myPhoneNumbers
是一个数组,因此您可以使用 myPhoneNumbers.first
而不是循环。
if let myPhoneNumbers = person.phoneNumbers?.allObjects as? [PhoneNumber] {
mainPhoneNumber = myPhoneNumbers.first
}
但是,正如已经指出的那样,您应该对您的集合强加某种顺序,以便执行此代码的结果对于任何给定的集合都是相同的。武断的结果通常是不好的。
既然你提到你正在使用 Core Data,我建议在你的 Person 实体上添加一个方便的 属性 到 return phone 数字作为排序数组。
如果您的实体看起来像这样...
class PhoneNumber: NSManagedObject {
@NSManaged var number: String
}
class PersonEntity: NSManagedObject {
@NSManaged var phoneNumbers: NSSet?
}
...你可以像这样创造一个便利 属性:
class PersonEntity: NSManagedObject {
@NSManaged var phoneNumbers: NSSet?
// Arrays are often easier to work with than sets,
// so provide a convenience property that returns
// phone numbers sorted
var phoneNumbersArray: [PhoneNumber] {
get {
if let phoneNumbers = phoneNumbers {
return (phoneNumbers.allObjects as! [PhoneNumber]).sorted() {
// here, sorting by phone number, but
// you can sort on whatever you want
.number > [=12=].number
}
}
// return empty array if set is nil
return [PhoneNumber]()
}
}
}
最后,一行代码得到第一个数字,如下所示:
mainPhoneNumber = person.phoneNumbersArray.first
我喜欢将这种类型的便利数组 属性 添加到我的所有具有集合的实体中。在我看来,数组更容易使用。这里我选择return一个空数组而不是一个nil数组,当集合为nil时。如果您可以处理 nil 和空 phone 设置相同,则此方法有效。
另请注意,如果 phoneNumbersArray
为空,则 .first
return 为零。