Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 带字典的快速过滤方法_Swift - Fatal编程技术网

Swift 带字典的快速过滤方法

Swift 带字典的快速过滤方法,swift,Swift,我有一个过滤器值的初始数组,例如: let filterValues : [String] = ["1", "4"] 我尝试过滤一个字典数组,其中每个字典包含一个或多个字典数组 数组的形式如下所示: let test : [[String : AnyObject]] = [ ["Objects": [ [ "value":"1", "tes

我有一个过滤器值的初始数组,例如:

let filterValues : [String] = ["1", "4"]
我尝试过滤一个字典数组,其中每个字典包含一个或多个字典数组

数组的形式如下所示:

  let test : [[String : AnyObject]] = [
        ["Objects":
            [
                [
                    "value":"1",
                    "test":"test"
                ],
                [
                    "value":"1",
                    "test":"test"
                ],
                [
                    "value":"1",
                    "test":"test"
                ],
                [
                    "value":"4",
                    "test":"test"
                ],
                [
                    "value":"2",
                    "test":"test"
                ],
                [
                    "value":"2",
                    "test":"test"
                ]
            ]
        ],
        ["Objects":
            [
                [
                    "value":"4",
                    "test":"test"
                ],
                [
                    "value":"2",
                    "test":"test"
                ],
                [
                    "value":"2",
                    "test":"test"
                ]
            ]
        ]
    ]
在我的初始测试阵列上应用filter方法后,我想要什么:

    [
            ["Objects":
                [
                    [
                        "value":"1",
                        "test":"test"
                    ],
                    [
                        "value":"1",
                        "test":"test"
                    ],
                    [
                        "value":"1",
                        "test":"test"
                    ],
                    [
                        "value":"4",
                        "test":"test"
                    ]
                ]
            ],
            ["Objects":
                [
                    [
                        "value":"4",
                        "test":"test"
                    ]
                ]
            ]
        ]
我在操场上的代码:

//Filter objects with matching enabled filters
let filtered = test.filter({
    let currentObjects = $0["Objects"] as! [[String:AnyObject]]
    let currentsObjectsFiltered = currentObjects.filter({
        if let value = $0["value"] as? String {
            return filterValues.contains(value)
        }
        return false
    })
    print(currentsObjectsFiltered)
    return false
})
数组“
currentsObjectsFiltered
”使用所需的值进行了良好的筛选。但是我想要原始的“
filtered
”数组和
test
数组的结构,而不是简单地用新对象过滤的新数组。我不知道如何处理过滤后的数组“
currentsObjectsFiltered

我想我现在必须使用它,因为我已经对对象进行了排序,但是如何

编辑

currentsObjectsFiltered
输出:

[["value": 1, "test": test], ["value": 1, "test": test], ["value": 1, "test": test], ["value": 1, "test": test], ["value": 4, "test": test], ["value": 4, "test": test]]
[["value": 1, "test": test], ["value": 1, "test": test], ["value": 1, "test": test], ["value": 1, "test": test], ["value": 4, "test": test], ["value": 4, "test": test]]
不要注意输出中结果值的数量我没有相同的测试数组,我只是发布输出以向您展示经过良好过滤的
currentsObjectsFiltered
的结构

我想我不能在一个过滤步骤中完成,因为过滤方法只应用于过滤数组的子级,而不是子级的子级。所以我可以只过滤“
对象”
”根据一条语句,我不能过滤“
对象”
”字典的子项,有人可以确认吗


有什么帮助吗?谢谢。

这是可能的,但是使用这些类型非常烦人。如果您发现自己正在创建新的
AnyObject
类型,那么您几乎肯定是在错误地处理问题
AnyObject
主要存在,因此您可以处理从Cocoa返回的
id
类型。它不是Swift的通用型

如果您首先将它们转换为类型安全结构,那么所有这些都会简单得多,您不必不断地将所有内容向上和向下转换到
AnyObject

下面是一个简单的结构,可以从您的一个字典中构造:

struct Object {
    let value: Int
    let test: String

    init?(jsonDictionary: [String: String]) {
        guard let
            value = jsonDictionary["value"].flatMap({Int($0)}),
            test = jsonDictionary["test"]
            else { return nil }

        self.value = value
        self.test = test
    }
}
将整个数据结构转换为以下内容非常简单:

let testArray = test.flatMap {
    ($0["Objects"] as? [[String: String]])?
        .flatMap(Object.init)
}
然后,根据您的需要对其进行过滤要容易得多:

let filterValues = [1, 4]

let filtered = testArray.map { objects in
    return objects.filter { filterValues.contains($0.value) }
}
即使您需要最终结果包含
AnyObject
,我仍然会这样做,然后编写一个函数将其序列化回原始
AnyObject
结构。直接使用
AnyObject
太容易出错,太复杂了。作为转换回
AnyObject
表单的示例,您可以使用如下函数:

func jsonArrayFromObjects(objectList: [[Object]]) -> [[String: AnyObject]] {
    return objectList.map { objects in
        ["Objects": objects.map { ["value": "\($0.value)", "test": $0.test] }]
    }
}

但除非绝对必要,否则我会避免这样做。即使您需要一本字典,也最好使用
[[String:[[String:String]]]
而不是
[[String:AnyObject]]

这是可能的,但是使用这些类型非常烦人。如果您发现自己正在创建新的
AnyObject
类型,那么几乎可以肯定您处理的问题是错误的。
AnyObject
大多存在,因此您可以处理从Cocoa返回的
id
类型。它不是通用类型f或者斯威夫特

如果您首先将它们转换为类型安全结构,那么所有这些都会简单得多,您不必不断地将所有内容向上和向下转换到
AnyObject

下面是一个简单的结构,可以从您的一个字典中构造:

struct Object {
    let value: Int
    let test: String

    init?(jsonDictionary: [String: String]) {
        guard let
            value = jsonDictionary["value"].flatMap({Int($0)}),
            test = jsonDictionary["test"]
            else { return nil }

        self.value = value
        self.test = test
    }
}
将整个数据结构转换为以下内容非常简单:

let testArray = test.flatMap {
    ($0["Objects"] as? [[String: String]])?
        .flatMap(Object.init)
}
然后,根据您的需要对其进行过滤要容易得多:

let filterValues = [1, 4]

let filtered = testArray.map { objects in
    return objects.filter { filterValues.contains($0.value) }
}
即使您需要最终结果来包含
AnyObject
,我仍然会这样做,然后编写一个函数将其序列化回原始的
AnyObject
结构。直接使用
AnyObject
非常容易出错和复杂。作为转换回
AnyObject
表单的示例,您可以使用如下函数:

func jsonArrayFromObjects(objectList: [[Object]]) -> [[String: AnyObject]] {
    return objectList.map { objects in
        ["Objects": objects.map { ["value": "\($0.value)", "test": $0.test] }]
    }
}
但除非是绝对必要的,否则我会避免这样做。即使你需要一本字典,也最好是将其设置为
[[String:[[String:String]]]
,而不是
[[String:AnyObject]]]