我在目标c中的旧功能是
+ (NSUInteger)getNumberOfDistinctUsers:(NSArray *)users {
NSArray* usersAfterPredicate = [users valueForKeyPath:@"@distinctUnionOfObjects.userName"];
return [usersAfterPredicate count]; }
我如何在swift中转换它,我试图这样的事情,但它崩溃“无法将类型'Swift.Array'的值转换为'Swift.AnyObject'”
static func getNumberOfDistinctUsers(users: [ICEPKReferenceDataUser]) -> Int {
var retval : Int = 0
if let usersAfterPredicate = (users as! AnyObject).valueForKeyPath("@distinctUnionOfObjects.userName") {
retval = usersAfterPredicate.count
}
return retval
}
我可以使用filter,map或Reduce来解决这个问题吗?我只是想使用属性username找出users数组中的distint用户。
编辑*强力方式
static func getNumberOfDistinctUsers(users: [ICEPKReferenceDataUser]) -> Int {
var retvalSet : Set<String> = []
for user in users {
retvalSet.insert(user.userName)
}
return retvalSet.count
}
答案 0 :(得分:4)
如您所料,您可以使用简单的地图简化代码:
static func getNumberOfDistinctUsers(users: [ICEPKReferenceDataUser]) -> Int {
return Set(users.lazy.map{$0.userName}).count
}
这使用了您可以使用任何其他序列初始化Set
的事实。
我在其中添加了lazy
以避免创建数组的额外副本。它可以使用或不使用,但我希望通过这种方式可以提高内存效率。 Array.map
创建了另一个Array
。 array.lazy.map
返回一个惰性集合,根据请求计算值。
那就是说,我不知道我的方法比你的蛮力&#34;办法。哪个更易于阅读或维护,这一点并不明显。我喜欢地图方法,但它可以是一种权衡(例如我必须知道添加lazy
,或者如果这是一个大数组我可以分配大量内存)。你的代码清楚地说明了发生了什么,所以我不认为那里有任何问题需要解决。
如果你真的想使用KVC,你需要将你的数组转换为NSArray
,而不是AnyObject
,但我怀疑上面的代码要快得多,而且是IMO也是更清晰,更简单。