2016-12-25 1 views
0

У меня есть этот массив:вызова фильтра на комплексном словаре (ассоциативное массив) в быстрых

class Filter { 

    var key = "" 
    var value = "" 

    init(key: String, value: String) { 
     self.key = key 
     self.value = value 
    } 

} 

let arry = [ 
    "a":[Filter(key:"city",value:"aachen"),Filter(key:"city",value:"augsburg")], 
    "b":[Filter(key:"city",value:"bremen"),Filter(key:"city",value:"berlin")] 
] 

, и я хочу, чтобы искать Аугсбурге и удалить его из словаря с функцией фильтра, так что результат выглядит следующим образом:

let arry = [ 
    "a":[Filter(key:"city",value:"aachen")], 
    "b":[Filter(key:"city",value:"bremen"),Filter(key:"city",value:"berlin")] 
] 

Я попробовал его с большим количеством фильтров и карты constelations, но я всегда получаю эту структуру как результат:

let arry = [ 
    ["a":[Filter(key:"city",value:"aachen")]], 
    ["b":[Filter(key:"city",value:"bremen"),Filter(key:"city",value:"berlin")]] 
] 

, например, с помощью этого фильтра:

arry.map({ key,values in 

    return [key:values.filter{$0.value != "augsburg"}] 
}) 

Что здесь проблема? Как фильтровать и отображать более сложные объекты?

+0

Прежде всего, ваш массив - это словарь, и почему вы делаете это настолько сложным, не думаете ли вы вместо того, чтобы создавать класс Filter с ключом и значением свойства, вам нужно сделать его с первым символом, который содержит первый позже города и второго массива String, который содержит все название города для этого объекта. –

+0

Связанные: http://stackoverflow.com/questions/24116271/whats-the-cleanest-way-of-applying-map-to-a-dictionary-in-swift. –

ответ

1

Может быть, одна вещь, которую вы должны знать, что map метод Dictionary возвращает Array, не Dictionary.

public func map<T>(_ transform: (Key, Value) throws -> T) rethrows -> [T] 

Итак, если вы хотите, отфильтрованный результат как Dictionary, вам, возможно, придется использовать reduce:

class Filter: CustomStringConvertible { 

    var key = "" 
    var value = "" 

    init(key: String, value: String) { 
     self.key = key 
     self.value = value 
    } 

    //For debugging 
    var description: String { 
     return "<Filter: key=\(key), value=\(value)>" 
    } 
} 

let dict = [ 
    "a":[Filter(key:"city",value:"aachen"),Filter(key:"city",value:"augsburg")], 
    "b":[Filter(key:"city",value:"bremen"),Filter(key:"city",value:"berlin")] 
] 

let filteredDict = dict.reduce([:]) {tempDict, nextPair in 
    var mutableDict = tempDict 
    mutableDict[nextPair.key] = nextPair.value.filter {$0.value != "augsburg"} 
    return mutableDict 
} 

(Как правило, Swift Dictionary является реализация на основе хэш-таблицы ассоциативного массива, но вы .. следует лучше избегать имен arry для Dictionary переменных Такое именование так запутанно)

Или еще просто использовать для в цикле:

var resultDict: [String: [Filter]] = [:] 
for (key, value) in dict { 
    resultDict[key] = value.filter {$0.value != "augsburg"} 
} 
print(resultDict) //->["b": [<Filter: key=city, value=bremen>, <Filter: key=city, value=berlin>], "a": [<Filter: key=city, value=aachen>]] 
+3

Предпочтительным является цикл for-in, поскольку он может напрямую мутировать результирующий словарь, тогда как использование 'reduce' создает промежуточный словарь для каждой итерации, заставляя его работать в квадратичном, а не в линейном времени. – Hamish

Смежные вопросы