SwiftArray中不存在filteredArrayUsingPredicate


67

我在数组中有“ 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”的用户。


1
嘟!iOS 8是beta版,XCode 6也是如此。
nicael 2014年

所以我不能用beta版过滤吗?我是iOS新手,如果我做错了任何事情,请使我正确..
Mani murugan 2014年

1
@Manimurugan nicael的意思是,您同意不公开讨论Apple的Beta。我不确定这是否适用于此,因为Swift书和库参考是在没有附加任何条件的情况下公开发布的。
谢尔盖·卡里尼琴科2014年

Answers:


121

Swift数组有一个.filter需要闭包的方法-可以做到这一点:

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

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

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

两者之间的区别在于,第一种是使用结尾闭包语法,速记参数名称,类型推断和隐式返回。您可以在Apple的Swift文档中阅读有关闭包的更多信息


你能告诉我有关$符号的情况吗。.这个有什么用?
Mani murugan 2014年

2
$0是简写参数名称。我将添加更多细节。
Nate Cook

如果它是字典数组,那么我该如何实现谓词来过滤userID == 1的数据(如果用户ID是Dictionary的键)?
Mani murugan 2014年

1
@Manimurugan,请参阅我的回答
karthikPrabhu Alagu 2014年

1
NSPredicate vs Pure Swift过滤器,哪个是更好的(更快,可扩展的)解决方案?
克里斯蒂安·卡多佐

102

您也可以使用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)");
}

1
@karthik Prabhu如果您有一个结构数组而不是一个字典数组,该怎么办? let filteredArray = arrNames.filter { namePredicate.evaluateWithObject($0) }; 该行给我的错误是“类型'myStruct'不符合协议'AnyObject'”
Hobsie 2014年

1
我更喜欢您的解决方案,因为NSPredicates比简单的字符串比较功能更强大。仅以简单的方式比较不区分大小写的可能性:let predicate = NSPredicate(format: "description contains[c] %@", argumentArray: [searchText])
blackjacx 2014年

太棒了!在寻找这个。当您要进行ObjectiveC快速转换而又不想真正接触谓词逻辑时,这确实很有用。
维纳亚克

5

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

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
})

您可以参考本文以获得更多信息。过滤字典或对象属性的Swift数组


2

在快速3或4中,您可以使用NSPredicate With Array

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


1

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

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)}

就像冠军。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.