解决 Swift 中过多的 else-if 语句 3
Resolving too many else-if statements in Swift 3
问题:给定函数的输入,测试每个用户以确保他们符合以下条件:
1. users数组中的每个用户不能与当前用户共享一个聊天室。 (聊天室对象有两个属性 'firstUserId' 和 'secondUserId'.
2.users数组中的每个用户都不是当前用户。
3. users 数组中的每个用户都在当前用户的 5 英里半径范围内。
在完成处理程序的调用视线中,我检查 User 对象的值是否为 true,如果是,我将其作为潜在匹配项显示给当前用户。
现在,我很快就用暴力破解了这个解决方案,但每次看到它都会感到畏缩。看起来效率很低。非常感谢有关更优雅解决方案的任何提示!
typealias validUsersCompletionHandler = (_ users: [User: Bool]) -> Void
private func validateNewUsers(currentUser: User, users: [User], chatrooms: [Chatroom], completionHandler: validUsersCompletionHandler?) {
var results: [User: Bool] = [:]
let currentUserCoords = CLLocation(latitude: currentUser.latitude, longitude: currentUser.longitude)
for user in users {
let newUserCoords = CLLocation(latitude: user.latitude, longitude: user.longitude)
let distance = currentUserCoords.distance(from: newUserCoords)
// // 1 mile = 1609 meters, 8046.72 = 5 miles.
for chatroom in chatrooms {
if currentUser.id == chatroom.firstUserId && user.id == chatroom.secondUserId {
results[user] = false
} else if currentUser.id == chatroom.secondUserId && user.id == chatroom.firstUserId {
results[user] = false
} else if user.id == currentUser.id {
results[user] = false
} else if distance > 8046.72 {
results[user] = false
} else {
results[user] = true
}
}
}
completionHandler?(results)
}
// ********************************************** ******************************
// 下面是我修改后的方法。我想稍微优雅一点?
// ********************************************** ******************************
typealias validUsersCompletionHandler = (_ users: [User: Bool]) -> Void
private func validateNewUsers(currentUser: User, users: [User], chatrooms: [Chatroom], completionHandler: validUsersCompletionHandler?) {
var results: [User: Bool] = [:]
var isInRange = false
var distance: Double = 0 {
didSet {
if distance > 8046.72 {
isInRange = false
} else {
isInRange = true
}
}
}
let currentUserCoords = CLLocation(latitude: currentUser.latitude, longitude: currentUser.longitude)
let currentUserId = currentUser.id
for user in users {
let userId = user.id
let newUserCoords = CLLocation(latitude: user.latitude, longitude: user.longitude)
distance = currentUserCoords.distance(from: newUserCoords)
// // 1 mile = 1609 meters, 8046.72 = 5 miles.
for chatroom in chatrooms {
switch (currentUserId, userId, isInRange) {
case (chatroom.firstUserId,chatroom.secondUserId, _), (_, _, false),(chatroom.secondUserId, chatroom.firstUserId, _), (_, currentUserId, _): results[user] = false
default: results[user] = true
}
}
}
completionHandler?(results)
}
}
你可以用 switch 替换 if 语句...或者你可以用
(currentUserId, userId)
//always check for optionals
guard let currentUserId = currentUser.id, let userId = user.id, else{
return
}
//The switch should have this format:
switch (currentUserId, userId){
//currentUserId == chatroom.firstUserId, userId = chatroom.secondUserId)
case (chatroom.firstUserId,chatroom.secondUserId):
//do your things
break
case (chatroom.secondUserId,firstUserId):
//do other things
break
default:
break
}
您甚至可以使用带声明的大小写或比较更多选项:
switch value{
case let x where value > 10:
//When value is bigger than 10..etc
default:
break
}
祝编码愉快:)
或者,您可以将元组值存储在 struc 中的某处(应该稍微更改一下逻辑),但您可以这样做:
struct myBeautifulCases{
static let userIsCurrent = (_,currentUserId,_)
static let sameChatroom = (chatroom.secondUserId, chatroom.firstUserId, _)
static let sameChatroomAlt = (chatroom.secondUserId, chatroom.firstUserId, _)
static let isWithinRange = case (_, _, false)
}
现在你可以用变量名覆盖丑陋的元组,但你应该稍微改变一下逻辑:)祝你好运和成功的项目:)
问题:给定函数的输入,测试每个用户以确保他们符合以下条件:
1. users数组中的每个用户不能与当前用户共享一个聊天室。 (聊天室对象有两个属性 'firstUserId' 和 'secondUserId'.
2.users数组中的每个用户都不是当前用户。
3. users 数组中的每个用户都在当前用户的 5 英里半径范围内。
在完成处理程序的调用视线中,我检查 User 对象的值是否为 true,如果是,我将其作为潜在匹配项显示给当前用户。
现在,我很快就用暴力破解了这个解决方案,但每次看到它都会感到畏缩。看起来效率很低。非常感谢有关更优雅解决方案的任何提示!
typealias validUsersCompletionHandler = (_ users: [User: Bool]) -> Void
private func validateNewUsers(currentUser: User, users: [User], chatrooms: [Chatroom], completionHandler: validUsersCompletionHandler?) {
var results: [User: Bool] = [:]
let currentUserCoords = CLLocation(latitude: currentUser.latitude, longitude: currentUser.longitude)
for user in users {
let newUserCoords = CLLocation(latitude: user.latitude, longitude: user.longitude)
let distance = currentUserCoords.distance(from: newUserCoords)
// // 1 mile = 1609 meters, 8046.72 = 5 miles.
for chatroom in chatrooms {
if currentUser.id == chatroom.firstUserId && user.id == chatroom.secondUserId {
results[user] = false
} else if currentUser.id == chatroom.secondUserId && user.id == chatroom.firstUserId {
results[user] = false
} else if user.id == currentUser.id {
results[user] = false
} else if distance > 8046.72 {
results[user] = false
} else {
results[user] = true
}
}
}
completionHandler?(results)
}
// ********************************************** ******************************
// 下面是我修改后的方法。我想稍微优雅一点?
// ********************************************** ******************************
typealias validUsersCompletionHandler = (_ users: [User: Bool]) -> Void
private func validateNewUsers(currentUser: User, users: [User], chatrooms: [Chatroom], completionHandler: validUsersCompletionHandler?) {
var results: [User: Bool] = [:]
var isInRange = false
var distance: Double = 0 {
didSet {
if distance > 8046.72 {
isInRange = false
} else {
isInRange = true
}
}
}
let currentUserCoords = CLLocation(latitude: currentUser.latitude, longitude: currentUser.longitude)
let currentUserId = currentUser.id
for user in users {
let userId = user.id
let newUserCoords = CLLocation(latitude: user.latitude, longitude: user.longitude)
distance = currentUserCoords.distance(from: newUserCoords)
// // 1 mile = 1609 meters, 8046.72 = 5 miles.
for chatroom in chatrooms {
switch (currentUserId, userId, isInRange) {
case (chatroom.firstUserId,chatroom.secondUserId, _), (_, _, false),(chatroom.secondUserId, chatroom.firstUserId, _), (_, currentUserId, _): results[user] = false
default: results[user] = true
}
}
}
completionHandler?(results)
}
}
你可以用 switch 替换 if 语句...或者你可以用 (currentUserId, userId)
//always check for optionals
guard let currentUserId = currentUser.id, let userId = user.id, else{
return
}
//The switch should have this format:
switch (currentUserId, userId){
//currentUserId == chatroom.firstUserId, userId = chatroom.secondUserId)
case (chatroom.firstUserId,chatroom.secondUserId):
//do your things
break
case (chatroom.secondUserId,firstUserId):
//do other things
break
default:
break
}
您甚至可以使用带声明的大小写或比较更多选项:
switch value{
case let x where value > 10:
//When value is bigger than 10..etc
default:
break
}
祝编码愉快:)
或者,您可以将元组值存储在 struc 中的某处(应该稍微更改一下逻辑),但您可以这样做:
struct myBeautifulCases{
static let userIsCurrent = (_,currentUserId,_)
static let sameChatroom = (chatroom.secondUserId, chatroom.firstUserId, _)
static let sameChatroomAlt = (chatroom.secondUserId, chatroom.firstUserId, _)
static let isWithinRange = case (_, _, false)
}
现在你可以用变量名覆盖丑陋的元组,但你应该稍微改变一下逻辑:)祝你好运和成功的项目:)