在Swift 3

时间:2017-05-28 18:17:58

标签: swift if-statement nested-loops

问题:给定函数的输入,测试每个用户以确保它们符合以下条件: 1.用户阵列中的每个用户都不能与当前用户共享聊天室。 (聊天室对象有两个属性" firstUserId'和' secondUserId'。
2. users阵列中的每个用户都不是当前用户。 3.用户阵列中的每个用户都在当前用户的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)

}

}

2 个答案:

答案 0 :(得分:2)

您可以使用开关替换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
    }

为了更好地使用,请参阅:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html

祝快乐编码:)

答案 1 :(得分:-1)

或者,你可以将你的元组值存储在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)

} 

现在你可以用变量名覆盖丑陋的元组,但是你应该改变一下逻辑:)祝你好运和成功的项目:)