У меня есть массив библиотек под названием uniLib
. Вот как это выглядит, когда я его распечатываю (это лишь малая часть):
["Université de Limoges": "France", "Vytautas Magnus University": "Lithuania", "Universidade Federal de Sergipe": "Brazil", "Instituto Politécnico de Lisboa": "Portugal", "Universidad de San Buenaventura": "Colombia", "Universitas Widyatama": "Indonesia", "Zhengzhou University of Technology": "China"]
У нас есть список университетов с соответствующей страной, и я хотел бы отфильтровать этот словарь по стране, например «Франция», и я должен получить новый массив словарей (или массив университетов, если это возможно). Я новичок в Swift. Я искал некоторое время, но я не могу найти ничего, чтобы решить эту проблему.
Вот как выглядит мой массив и как он определен:
universityNames = json[].arrayValue.map {$0["name"].stringValue}
countryNames = json[].arrayValue.map {$0["country"].stringValue}
// merge arrays
var uniLib : [String:String] = [:]
for (index, element) in universityNames.enumerated() {
uniLib[element] = countryNames[index] }
Вы могли бы сделать что-то вроде этого :).
let universities = ["Université de Limoges": "France", "Vytautas Magnus University": "Lithuania", "Universidade Federal de Sergipe": "Brazil", "Instituto Politécnico de Lisboa": "Portugal", "Universidad de San Buenaventura": "Colombia", "Universitas Widyatama": "Indonesia", "Zhengzhou University of Technology": "China"]
func filterUniversities(country: String) -> [String] {
return universities
.compactMap { tuple in
return tuple.value == country ? tuple.key : nil
}
}
print(filterUniversities(country: "France"))
Это вернет ["Université de Limoges"]
, что, я надеюсь, вы ищете, основываясь на вопросе.
Обновленное решение на основе комментария:
Я не уверен на 100%, каков ожидаемый результат, поэтому я создал два варианта:
let allUniversities = [
["Université de Limoges": "France", "Universidad de San Buenaventura": "Colombia", "Universitas Widyatama": "Indonesia", "Zhengzhou University of Technology": "China"],
["Universidade Federal de Sergipe": "Brazil", "Vytautas Magnus University": "Lithuania"],
["Instituto Politécnico de Lisboa": "Portugal", "Sorbonne": "France"]
]
func filterUniversities(country: String) -> [String] {
return allUniversities
.lazy
.reduce([String]()) { (result, universities) in
let filteredUniversities = universities.compactMap { $0.value == country ? $0.key : nil }
return result + filteredUniversities
}
}
print(filterUniversities(country: "France"))
func filterUniversityDictionaries(country: String) -> [[String: String]] {
return allUniversities.lazy.filter { $0.values.contains(country) }
}
print(filterUniversityDictionaries(country: "France"))
Это даст вам следующий результат:
["Université de Limoges", "Sorbonne"]
[["Zhengzhou University of Technology": "China", "Universidad de San Buenaventura": "Colombia", "Université de Limoges": "France", "Universitas Widyatama": "Indonesia"], ["Instituto Politécnico de Lisboa": "Portugal", "Sorbonne": "France"]]
uniLib.lazy // Lazy so we don't have to allocate a temporary
.filter { $0.value == country } // Find key/value pairs where value == country
.map { $0.key } // Return the key (name)
Единственная причина возиться с lazy
здесь заключается в том, что uniLib
было бы довольно большим, и шаг filter
имел бы тенденцию находить много элементов. Без лени есть временный словарь, созданный filter
и тут же выброшенный.
Дело в том, что это лишь малая часть моего массива. У меня есть несколько словарей, в которых Франция указана как страна. Поэтому я хочу отфильтровать его и получить массив со всеми словарями, в которых Франция указана как страна.