Swift: отфильтровать ключ словаря из структуры из массива, что необязательно - PullRequest
0 голосов
/ 07 марта 2019
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. Массив со всеми ключами из свойства сообщения от дел - tag1 и tag2 (в нем нет nils). Я просто попробовал все, что я знаю, я не мог этого сделать. Пробовал с фильтрацией, получил опционально.

  2. Нет предварительных просмотров без тега, поэтому нет необходимости в массиве с ними. Мне нужен только список с тегами, чтобы отсортировать его и показать соответствующие превью от дел. Вот почему мне нужно знать, как получить доступ к этим превью от дел. Допустим, в UITableView:

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

Конечно, словарь с [tags: previews] также будет идеальным!

Заранее спасибо! Я надеюсь, что то, что я хочу, возможно.

Ответы [ 2 ]

1 голос
/ 07 марта 2019

Вот массив, содержащий только элементы из 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?]
}
0 голосов
/ 07 марта 2019

Мне не совсем понятно, что вы пытаетесь сделать, однако, это отфильтрует ваш массив cases только в Test объектах, которые содержат ненулевой values в словаре сообщений:

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

Переменная nonNil теперь содержит объекты Test, где title равно «2», а title «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"]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...