如何更有效地处理此数组



我有一个名称数组,如下所示。["John Doe","Mary Blog"]

我想做的是处理这个数组,并返回一个首字母如下的数组。

["JD"、"MB"]

我已经完成了这项工作,但我的代码丑陋且效率低下(嵌套循环(。对于像我的例子中这样的小数组来说,这可能很好。

如何更有效地处理阵列?

let contacts = ["John Doe", "Mary Blog"]
var initalsArray: [String] = []
let names = contacts.map {$0}
for name in names {
var initals: String = ""
let fullname = name.components(separatedBy: " ")
for part in fullname {
if part.count > 0 {
initals += part[0]
}
}
initalsArray.append(initals)
}

我没有将其效率与上述答案进行比较,但如果您正在处理names,使用PersonNameComponentsFormatter将对您有很大帮助。请查看此处的文档。

在您的情况下,下面的代码提供了所需的输出。

let formatter = PersonNameComponentsFormatter()
let contacts = ["John Doe", "Mary Blog"]
var initalsArray: [String] = []
for contact in contacts {
if let name = formatter.personNameComponents(from: contact) {
formatter.style = .abbreviated
initalsArray.append(formatter.string(from: name))
}
}

output -> ["JD", "MB"]

必须处理数组中的所有元素。

对于每个元素,必须检测空格并检索下一个字母。

然后,必须使用连接的大写字母构建输出数组。

所以我真的不明白你怎么能避免双重循环。

只有if part.count > 0是不必要的。


或者,您可以自己扫描字符串以避免生成中间数组fullname

您可能也可以通过正则表达式处理来获得结果,但这将是一把大锤。不要。


内部循环的可能实现。(很抱歉,如果这是无效的,我不认识斯威夫特(。

var space: Bool = true
for c in name {
if space && c != ' ' {
initials+= c
} 
space= c == ' '
}

请注意,(可选(额外条件c != ' '可防止出现双空格。

您可以使用map来移除一些自己的循环

let contacts = ["John Doe", "Mary Blog"]
let result = contacts.map { $0.components(separatedBy: .whitespacesAndNewlines).map { String($0.prefix(1)) }.joined(separator: "") }
print(result)

我不知道这是否更快,也许它给了苹果一个机会来进行一些难以进行的优化

实际上,这个答案虽然相似,但可能会更快一点

let contacts = ["John Doe", "Mary Blog"]
let result = contacts.map { $0.components(separatedBy: .whitespacesAndNewlines).reduce("") { $0 + String($1.prefix(1)) } }
print(result)

我只是把它添加到前面的第一个字母的字符串中

最新更新