避免许多情况

时间:2018-08-13 09:25:02

标签: ios swift

我有6个字符串(文本,年份,年龄,...),我想根据它们来过滤数组...我想先检查字符串是否为空。如果不为空,则添加到将if条件作为&& ..但如何执行这样的事情而又不需要在每个字符串之间写很多if条件?

我想避免做这样的事情:

if self.searchtext != "" && self.qualification != ""{

}else if self.searchtext != "" && self.qualification != "" && self.gender != ""{

}else if self.searchtext != "" && self.qualification != "" && self.gender != "" && self.year != ""{

}else if self.searchtext != "" && self.qualification != "" && self.gender != "" && self.year != "" && self.major != ""{

}
....

该怎么做?

if self.searchtext != ""{
                            if user.name.contains(find: self.searchtext) || user.mobile.contains(find: self.searchtext) || user.email.contains(find: self.searchtext){
                                DispatchQueue.main.async {
                                    self.phones.append(user.mobile)
                                    self.names.append(user.name)
                                }
                            }
                        }else if self.qualification != ""{
                            if user.qualification.contains(find: self.qualification){
                                DispatchQueue.main.async {
                                    self.phones.append(user.mobile)
                                    self.names.append(user.name)
                                }
                            }
                        }else if self.gender != ""{
                            if user.gender.contains(find: self.gender){
                                DispatchQueue.main.async {
                                    self.phones.append(user.mobile)
                                    self.names.append(user.name)
                                }
                            }
                        }else if self.year != ""{
                            if user.graduateYear.contains(find: self.year){
                                DispatchQueue.main.async {
                                    self.phones.append(user.mobile)
                                    self.names.append(user.name)
                                }
                            }
                        }else if self.major != ""{
                            if user.specialization.contains(find: self.major){
                                DispatchQueue.main.async {
                                    self.phones.append(user.mobile)
                                    self.names.append(user.name)
                                }
                            }
                        }else if self.city != ""{
                            if user.city.contains(find: self.city){
                                DispatchQueue.main.async {
                                    self.phones.append(user.mobile)
                                    self.names.append(user.name)
                                }
                            }
                        }
                    }

这是我正在工作的..但是当我希望它对所有无空字符串都像AND时,它将作为OR起作用

4 个答案:

答案 0 :(得分:3)

这是一个从LinkedIn's style guide复制的段落

  

使用警卫声明

     

3.11.1通常,我们倾向于在适用的情况下使用“提前返回”策略,而不是在if语句中嵌套代码。在这种用例中使用保护语句通常会有所帮助,并且可以提高代码的可读性。

// PREFERRED
func eatDoughnut(at index: Int) {
    guard index >= 0 && index < doughnuts.count else {
        // return early because the index is out of bounds
        return
    }

    let doughnut = doughnuts[index]
    eat(doughnut)
}

// NOT PREFERRED
func eatDoughnut(at index: Int) {
    if index >= 0 && index < doughnuts.count {
        let doughnut = doughnuts[index]
        eat(doughnut)
    }
}

这是我个人所做的事情,并且是避免嵌套if的好习惯。

就您而言,您可以做几件事。首先,请使用.isEmpty而不是将字符串与空字符串("")进行比较。如果您唯一的目的是检查所有字符串是否为空,则可以这样完成:

    let strings = [searchtext, qualification, ...]
    guard strings.filter({ $0.isEmpty }).count == 0 else {
        return
    }

    // Code that only works if all fields have values

答案 1 :(得分:2)

我们当然可以简化很多事情。

我将从包装搜索条件到一个对象开始:

struct UserSearchCriteria {
   var searchText = ""
   var gender = ""
   var qualification = ""
   ...

   init() {}
}

然后,您可以使用一个变量而不是X变量:

var searchCriteria = UserSearchCriteria()

然后您可以添加一个简单的匹配方法:

extension UserSearchCriteria {
   func matchesUser(_ user: User) -> Bool {
      if !searchText.isEmpty && [user.name, user.mobile, user.email].contains(where: { $0.contains(find: searchText) }) { 
         return true
      }

      if !qualification.isEmpty && user.qualification.contains(find: qualification) {
         return true
      }

      ...

      return false
   }
}

那么您的大病归结为:

if self.searchCriteria.matches(user) {
   DispatchQueue.main.async {
      self.phones.append(user.mobile)
      self.names.append(user.name)
   }
}

您不能真正避免这些条件,但是可以在不重复代码的情况下简化它们并更好地组织它们。

似乎您想匹配所有搜索条件,然后将匹配方法更改为:

func matchesUser(_ user: User) -> Bool {
      if !searchText.isEmpty && ![user.name, user.mobile, user.email].contains(where: { $0.contains(find: searchText) }) { 
         return false
      }

      if !qualification.isEmpty && !user.qualification.contains(find: qualification) {
         return false
      }

      ...

      return true
   }

(请注意双重否定-否定contains条件并返回false)。

答案 2 :(得分:1)

您可以使用Guard statement提前退出范围。

  

保护语句用于将程序控制权移出作用域   如果不满足一个或多个条件。

只有在所有字段都不为空的情况下才会通过。

guard self.searchtext != "", self.qualification != "", self.gender != "", self.year != "", self.major != "" else { return }

更新:

guard let searchText = self.searchtext, !searchText.isEmpty else { return }
// do something with `searchText`. Here the above conditions will be true. 

或者您可以使用if-let

if let searchText = self.searchtext, !searchText.isEmpty {
    // do with `searchText`(non-optional). 
} else {
    // conditions failed.
}

如果您要过滤数组,则只需使用array.filter

let filteredUsers = usersArray.filter {
        let isSame = false
        if let name = $0.name { 
             isSame = true
             isSame = isSame && name.contains(searchtext)
        }
        if let mobile = $0.mobile { 
             isSame = true
             isSame = isSame && mobile.contains(searchtext)
        }
        if let age = $0.age { 
             isSame = true
             isSame = isSame && age.contains(searchtext)
        }
        if let gender = $0.gender { 
             isSame = true
             isSame = isSame && gender.contains(searchtext)
        }

        return isSame


        //guard let name = $0.name, let mobile = $0.mobile, let email = $0.email else { return false }
        //return name.contains(searchtext) || mobile.contains(searchtext) || email.contains(searchtext)
}

答案 3 :(得分:0)

Swift包含Dim i As Integer Dim s As Integer For i = 1 To 20 For s = 1 To 20 Range("Active_Scenaro") = s Calculate Range("Scenario(i)").Value = Range("SensitivityResults").Value Next s Next i 语句。 guard语句之后的行仅在保护条件为true时才执行。像guard语句一样,如果条件为false,则if/else子句就会运行。

else

针对您的情况:

guard condition else {
  // false: execute some code
}

// true: execute some code

guard self.searchtext && self.qualification && self.gender && self.year && self.major else { return } // execute some code 语句将退出函数或方法。

更多信息可以在“提前退出”部分的文档中找到:

https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html