如果arrayOfA中的元素数量大约为1000,而arrayOfB中的元素数量大约为100 000(运行时间大约是几分钟),则下面的代码存在速度问题。如何提高速度?
let arrayOfA = [(String, String)]() //second string in tuple is about 30 characters
let arrayOfB = [String]() //string is about 200 characters
var arrayOfC = [(String, Int)]()
for i in 0..<arrayOfA.count
{
var amount = Int()
let name = arrayOfA[i].0 + " " + arrayOfA[i].1
for j in 0..<arrayOfB.count
{
if arrayOfB[j].range(of: arrayOfA[i].1) != nil
{
amount += 1
}
}
if amount > 0
{
arrayOfC += [(name, amount)]
}
}
更新
与此同时,我制作了另一个代码,速度提高了大约4倍。这个想法是为了避免函数.range(of: string)
的不必要的重复步骤。因此,第一步是使用间隔"_"
加入读取然后,我可以使用扩展方法Range<String.Index>
搜索stringOfarrayOfB
中的stringA的所有searchForStringInString
(可以在Range<String.Index>
中找到stringIn
的所有stringOut
。
let stringOfarrayOfB = arrayOfB.joined(separator: "_")
for i in 0..<arrayOfA.count
{
var amount = Int()
let arrayOfRanges = stringOfarrayOfB.searchForStringInString(stringOut: stringOfarrayOfB, stringIn: arrayOfA[i].1)
amount = arrayOfRanges.count
if amount > 0
{
let name = arrayOfA[i].0 + " " + arrayOfA[i].1
arrayOfC += [(name, amount)]
}
}
答案 0 :(得分:1)
这是使用建议的评论更改后的代码。
let arrayOfA = [(String, String)]() //second string in tuple is about 30 characters
let arrayOfB = [String]() //string is about 200 characters
var arrayOfC = [(String, Int)]()
for i in 0..<arrayOfA.count
{
var amount = Int()
for (index, stringB) in arrayOfB.enumerate().reverse()
{
if stringB.range(of: arrayOfA[i].1) != nil
{
amount += 1
arrayOfB.removeAtIndex(index)
}
}
if amount > 0
{
let name = arrayOfA[i].0 + " " + arrayOfA[i].1
arrayOfC += [(name, amount)]
}
}
<强>更新强>
相同的功能而不反转数组
let arrayOfA = [(String, String)]() //second string in tuple is about 30 characters
let arrayOfB = [String]() //string is about 200 characters
var arrayOfC = [(String, Int)]()
for i in 0..<arrayOfA.count
{
var amount = Int()
var indexesToDelete = []
for (index, stringB) in arrayOfB.enumerate()
{
if stringB.range(of: arrayOfA[i].1) != nil
{
amount += 1
indexesToDelete.append(index)
}
}
for (index, indexToDelete) in indexesToDelete {
arrayOfB.removeAtIndex(indexToDelete - index)
}
if amount > 0
{
let name = arrayOfA[i].0 + " " + arrayOfA[i].1
arrayOfC += [(name, amount)]
}
}
答案 1 :(得分:-2)
你可以试试这个。
for i in 0..<arrayOfA.count {
var amount = Int()
let name = arrayOfA[i].0 + " " + arrayOfA[i].1
let tempArr = arrayOfB.filter { (string) -> Bool in
string.rangeOfString(arrayOfA[i].1) != nil
}
amount = tempArr.count
if amount > 0 {
arrayOfC += [(name, amount)]
}
}
arrayOfC += [(name, amount)]
}
在任何情况下,过滤器应该比循环更有效。