Swift:从数组的结构中过滤字典键,这是可选的

时间:2019-03-07 19:46:18

标签: arrays swift dictionary struct optional

struct Test {
    var title: String
    var message: [String?: String?]

    init(title: String, message: [String?:String?]) {
        self.title = title
        self.message = message
    }
}

var cases = [
     Test(title: "1", message: ["tag1": nil]),
     Test(title: "2", message: ["tag2": "preview2"]),
     Test(title: "3", message: [nil:nil]),
     Test(title: "4", message: ["tag1":"preview4"])
]

现在,我想要:

  1. 一个数组,其中包含案例中message属性的所有键-tag1和tag2(其中没有nil)。我只是尝试了我所知道的一切,但无法做到。尝试筛选条件,有可选条件。

  2. 没有标签就没有预览,因此不需要带有它们的数组。我只需要带有标签的列表,即可对其进行排序并显示案例的相关预览。这就是为什么我需要知道一种如何从案例中访问这些预览的原因。假设在UITableView中:

    cell.previewLabel?.text = cases[indexPath.row].preview[//No idea what here]
    

当然,具有[tags: previews]的字典也很完美!

提前谢谢!我希望我想要的是可能的。

2 个答案:

答案 0 :(得分:1)

这里是一个数组,其中仅包含cases中的所有键和值都不为nil的元素:

let filtered = cases.filter { test in
    return test.message.allSatisfy({ entry in
        return entry.key != nil && entry.value != nil
    })
}

或使用速记符号:

let filtered = cases.filter {
    $0.message.allSatisfy({
        $0.key != nil && $0.value != nil
    })
}

有了结构,就有一个默认的初始化程序,因此您可以这样编写Test结构:

struct Test {
    var title: String
    var message: [String?: String?]
}

答案 1 :(得分:0)

我尚不清楚您要尝试做什么,但是,这会将您的cases数组过滤为仅Test个对象,该对象在消息中包含非nil values字典:

let nonNil = cases.filter { (test) -> Bool in
    return Array(test.message.values).filter({ (value) -> Bool in
        return value == nil
    }).count <= 0
}

变量nonNil现在包含Test对象,其中标题为“ 2”,标题为“ 4”。

如果您想要[tags:preview]字典,则可以进一步过滤。这样的事情会做到这一点:

let tags = nonNil.map( { $0.message} ).flatMap { $0 }.reduce([String:String]()) { (accumulator, current) -> [String:String] in
    guard let key = current.key, let value = current.value else { return accumulator }
    var accum = accumulator
    accum.updateValue(value, forKey: key)
    return accum
}

tags词典现在包含:["tag1": "preview4", "tag2": "preview2"]