【问题标题】:filteredArrayUsingPredicate does not exist in swift Arrayswift Array中不存在filteredArrayUsingPredicate
【发布时间】:2014-06-24 09:08:05
【问题描述】:

我在数组中有“UserDetails”结构对象..我想从数组中过滤对象。但是 Swift 数组中没有“filteredArrayUsingPredicate”选项。

我的数组创建

var arrayOfUsers:UserDetails[] = UserDetails[]()

我的用户详细信息代码是

struct UserDetails{
    var userName:String
    var userID:String
    var userAge:String
    func userDescription()->String{
        return "name " + userName + "age " + userID
    }
}

我创建对象的代码

        for a in 1...1000{
            var user:UserDetails = UserDetails(userName: "name", userID: String(a), userAge: "22")
            arrayOfUsers.append(user)
        }

现在我想过滤arrayOfUsers 的用户ID 为“1”。

【问题讨论】:

  • 哔! iOS 8 是测试版,XCode 6 也是。
  • 所以我不能用测试版过滤吗?我是iOS新手,如果我做错了什么,请纠正我..
  • @Manimurugan nicael 的意思是您已同意不公开讨论 Apple 的测试版。不过,我不确定这是否适用于这里,因为 Swift 书籍和图书馆参考资料是在没有附加任何条件的情况下向公众发布的。

标签: swift ios8 xcode6


【解决方案1】:

Swift 数组有一个 .filter 方法,它接受一个闭包——这样就可以了:

let filteredArray = arrayOfUsers.filter() { $0.userID == "1" }

可以通过多种方式简化闭包。闭包的完整声明看起来更像这样:

var filteredArray = arrayOfUsers.filter( { (user: UserDetails) -> Bool in
        return user.userID == "1"
    })

两者的区别在于第一个是使用尾随闭包语法、速记参数名称、类型推断和隐式返回。你可以阅读more about closures in Apple's Swift documentation

【讨论】:

  • 你能告诉我$符号..这个有什么用?
  • $0 是一个速记参数名称。我将添加更多细节。
  • 如果它是字典数组,那么我如何实现谓词来过滤用户ID == 1的数据(如果用户ID是字典的键)?
  • @Manimurugan 参考我的回答
  • NSPredicate vs Pure Swift 过滤器,哪个是更好(更快,可扩展)的解决方案?
【解决方案2】:

你也可以使用 NSPredicate

    var customerNameDict = ["firstName":"karthi","LastName":"alagu","MiddleName":"prabhu"];
    var clientNameDict = ["firstName":"Selva","LastName":"kumar","MiddleName":"m"];
    var employeeNameDict = ["firstName":"karthi","LastName":"prabhu","MiddleName":"kp"];
    var attributeValue = "karthi";

    var arrNames:Array = [customerNameDict,clientNameDict,employeeNameDict];


    var namePredicate =
        NSPredicate(format: "firstName like %@",attributeValue);

    let filteredArray = arrNames.filter { namePredicate.evaluateWithObject($0) };
    println("names = ,\(filteredArray)");

//结构过滤

struct myStruct
{
    var userid:String;
    var details:String;
    init() {
        userid = "default value";
        details = "default";
    }

};
var f1 = myStruct();
f1.userid = "1";
f1.details = "Good boy";

var f2 = myStruct();
f2.userid = "2";
f2.details = "Bad boy";
var arrNames1:Array = [f1,f2];
let filteredArrayStruct =  arrNames1.filter( { (user: myStruct) -> Bool in
    return user.userid == "1"
    })
println("filter array count = \(filteredArrayStruct.count)");
for  filteredValues in filteredArrayStruct
{
       println("filteredArrayStruct = ,\(filteredValues.details)");
}

【讨论】:

  • @karthik Prabhu 如果你有一个结构数组而不是字典数组,你会怎么做? let filteredArray = arrNames.filter { namePredicate.evaluateWithObject($0) }; 那行给了我错误“类型'myStruct'不符合协议'AnyObject'”
  • 我更喜欢您的解决方案,因为 NSPredicates 比简单的字符串比较更强大。只有以简单的方式比较不区分大小写的可能性:let predicate = NSPredicate(format: "description contains[c] %@", argumentArray: [searchText])
  • 太棒了!正在寻找这个。当您正在执行 ObjectiveC 到快速转换并且不想触及谓词逻辑时,这非常有用。
【解决方案3】:

如果您要过滤字典,您可以这样做。

var visitors = [["age" : 22], ["age" : 41], ["age" : 23], ["age" : 30]]

var filteredVisitors = visitors.filter({
    $0["age"] < 30
})

println(filteredVisitors)
//[["age" : 22], ["age" : 23]]

这同样适用于过滤其属性的结构

struct Person {
    var age : Int?
    init(age: Int) {
        self.age = age
    }
}

var eventAttendees = [Person(age: 22), Person(age: 41), Person(age: 23), Person(age: 30)]

var filteredAttendees = eventAttendees.filter({
    $0.age < 30
})

您可以参考这篇文章了解更多信息。 Filtering a Swift Array of Dictionaries or Object property

【讨论】:

    【解决方案4】:

    在 swift 3 或 4 中你可以使用 NSPredicateArray

    let pred : NSPredicate = NSPredicate(format: "points_status = %@", "0")
    let   approvalRequestArray =  approvalRequestOriginalArray.filtered(using: pred) as NSArray
    
    
    let provincesStartingWithM = NSPredicate(format: "name contains [cd] 'a'")
    
    provinces.filtered(using: provincesStartingWithM)
    

    欲了解更多信息,您可以访问此链接 GitHub

    【讨论】:

      【解决方案5】:

      事实证明,您不必一次只比较一个过滤器。您可以应用逻辑条件来扩大谓词的范围。例如:

      var foundArray = tempArray.filter{ String(describing:$0.id) .contains(searchText) || 
      $0.name .contains(searchText) || $0.summary! .contains(searchText) || 
      String(describing: $0.airDate).contains(searchText) || String(describing: $0.airTime).contains(searchText) || 
      String(describing: $0.runTime).contains(searchText)}
      

      像冠军一样工作。

      【讨论】:

        猜你喜欢
        • 2021-06-01
        • 2019-02-13
        • 2020-11-07
        • 1970-01-01
        • 2020-06-20
        • 1970-01-01
        • 1970-01-01
        • 2017-04-14
        • 1970-01-01
        相关资源
        最近更新 更多