我在从对象列表中提取数据时遇到了一些麻烦,我正在学习函数式编程概念。
struct Country {
let name: String
}
let country1 = Country(name: "Algeria")
let country2 = Country(name: "Angola")
let country3 = Country(name: "Belgium")
let countries = [country1, country2, country3]
我想要做的是一个字典,其中键是第一个字符,值是以这个字符开头的所有国家/地区的列表。在我的示例中,我将得到:
let dic = ["A": [country1, country2], "B":[country3]]
我知道如何使用“丑陋的”for 循环来做到这一点。像这样:
for country in countries {
let first = country.name.first
if !sections.keys.contains(first) {
let matchedCountries = countries.filter {$0.name.hasPrefix(first)}
sections[first] = matchedCountries
}
}
我的问题是:有没有一种更实用的简单方法?
最佳答案
我不认为要不惜一切代价避免 for
循环(而且我个人不会求助于 for ... in
循环为“丑陋”:),在某些情况下,它们可能是最合适的结构。就是说,您可以在 countries
数组上使用 .forEach
(尽管本质上是 for ... in
循环)和只需将国家附加到现有键并为不存在的键值对创建新的键值对(String:[Country]
键值对)。例如:
/* your example above */
struct Country {
let name: String
}
let country1 = Country(name: "Algeria")
let country2 = Country(name: "Angola")
let country3 = Country(name: "Belgium")
let countries = [country1, country2, country3]
/* .forEach solution */
var countryDict: [String: [Country]] = [:]
countries.forEach {
if let first = $0.name.characters.first,
case let key = String(first) {
if let val = countryDict.removeValueForKey(key) {
countryDict[key] = val+[$0]
}
else {
countryDict[key] = [$0]
}
}
}
print(countryDict)
/* ["B": [Country(name: "Belgium")],
"A": [Country(name: "Algeria"), Country(name: "Angola")]] */
请注意,此方法的一个可能的好处是您不使用嵌套在外部 for
循环中的类似循环的结构(例如 .contains
和 .过滤器
);您只需要处理一次 countries
数组中的每个国家/地区。
关于swift - 使用函数式编程提取数组中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37334070/