在循环条件取决于字符串数组大小的 for 循环中从字符串数组中删除元素
Remove elements from string array while in a for loop whose looping condition depends on string array size
我有一个字符串数组,我想根据 indexPath 数组中的值从中删除元素,该数组是通过 table 行上的 2 指平移手势生成的。循环重复计数取决于字符串数组的大小,并且在每个循环中删除相关的字符串数组元素。
代码如下:
if let indexPaths = languagesTable.indexPathsForSelectedRows {
rowCount = rowCount - (indexPaths.count)
controllerData.deleteWordsForLanguage(languages: languages, indexPaths: indexPaths)
for indexPath in indexPaths {
print("inside 1st for loop in clearSelectedLanguages, indexPaths are: \(indexPaths)")
print("languages.count in clearSelectedLanguages in languagesView os: \(languages.count)")
for language in 0..<languages.count
print("indexPath.row == language is: \(indexPath.row == language) && indexPath.section == 0 is: \(indexPath.section == 0)")
if indexPath.row == language && indexPath.section == 0 {
print("inside 2nd for loop in clearSelectedLanguages in languages")
print("languages in clearSelectedLanguages before languages.remove in languagesView are: \(languages)")
languages.remove(at: language)
print("languages in clearSelectedLanguages in languagesView are: \(languages)")
}
}
}
}
controllerData.saveLanguages(languagesToSave: languages)
languagesTable.setEditing(false, animated: true)
languagesTable.reloadData()
enableSort()
enableDelete()
}
当我要求应用程序删除(按删除按钮)字符串数组的所有元素时,它会删除除一个元素之外的所有元素。我试过以不同的顺序排列字符串数组元素,它似乎不是特定于字符串元素值的,如果它是一个 3 元素数组,它总是中间元素。
我怀疑从原始大小定义所需循环数的数组中删除元素会导致第二个 for 循环出现问题。
一些调试控制台输出:
inside 1st for loop in clearSelectedLanguages, indexPaths are: [[0, 0], [0, 1], [0, 2]]
indexPath.row == language is: true && indexPath.section == 0 is: true
inside 2nd for loop in clearSelectedLanguages in languages
languages in clearSelectedLanguages in languagesView are: ["french", "spanish", "german"]
languages in clearSelectedLanguages in languagesView are: ["spanish", "german"]
indexPath.row == language is: false && indexPath.section == 0 is: true
indexPath.row == language is: false && indexPath.section == 0 is: true
inside 1st for loop in clearSelectedLanguages, indexPaths are: [[0, 0], [0, 1], [0, 2]]
indexPath.row == language is: false && indexPath.section == 0 is: true
indexPath.row == language is: true && indexPath.section == 0 is: true
inside 2nd for loop in clearSelectedLanguages in languages
languages in clearSelectedLanguages in languagesView are: ["spanish", "german"]
languages in clearSelectedLanguages in languagesView are: ["spanish"]
inside 1st for loop in clearSelectedLanguages, indexPaths are: [[0, 0], [0, 1], [0, 2]]
indexPath.row == language is: false && indexPath.section == 0 is: true
languages in saveLanguages in dataModel are: ["spanish"]
如您所见,第二组 if 条件失败,字符串数组的最后一个元素永远不会被删除。然后程序退出所有 for 循环并调用包含最终调试打印语句的方法。
使用循环按索引删除元素常常让我们感到困惑,因为目标索引会在执行循环时发生变化。
indexPaths
为 [[0, 0], [0, 1], [0, 2]]
,languages
为 ["french", "spanish", "german"]
,
[0, 0]
对于 "french"
[0, 1]
对于 "spanish"
[0, 2]
对于 "german"
删除第一个indexPath[0, 0]
时,可能OK:
languages in clearSelectedLanguages in languagesView are: ["french", "spanish", "german"]
languages in clearSelectedLanguages in languagesView are: ["spanish", "german"]
它删除相应的元素"french"
。
但是当删除第二个indexPath[0, 1]
时,您可能需要仔细检查输出。
languages in clearSelectedLanguages in languagesView are: ["spanish", "german"]
languages in clearSelectedLanguages in languagesView are: ["spanish"]
它删除(最初)第三个元素 "german"
而不是第二个元素 "spanish"
。因为一旦删除一个元素,数组中每个元素的索引都会改变。
因此,当您要删除第三个 indexPath [0, 2]
时,没有任何反应,因为单个元素数组 ["spanish"]
没有索引 2
.
的元素
处理这种情况的一种方法是以相反的顺序从下到上删除。
for indexPath in indexPaths.reversed() {
//...
}
但是双循环不是一种有效的方式,我会这样写:
if let indexPaths = languagesTable.indexPathsForSelectedRows {
rowCount = rowCount - (indexPaths.count)
controllerData.deleteWordsForLanguage(languages: languages, indexPaths: indexPaths)
print("indexPaths are: \(indexPaths)")
let rowsToRemove = Set(indexPaths.filter{[=13=].section == 0}.map{[=13=].row})
print("languages before filter are: \(languages)")
languages = languages.enumerated().filter{row,_ in !rowsToRemove.contains(row)}.map{}
print("languages after filter are: \(languages)")
controllerData.saveLanguages(languagesToSave: languages)
//...
}
请尝试一下。
我有一个字符串数组,我想根据 indexPath 数组中的值从中删除元素,该数组是通过 table 行上的 2 指平移手势生成的。循环重复计数取决于字符串数组的大小,并且在每个循环中删除相关的字符串数组元素。
代码如下:
if let indexPaths = languagesTable.indexPathsForSelectedRows {
rowCount = rowCount - (indexPaths.count)
controllerData.deleteWordsForLanguage(languages: languages, indexPaths: indexPaths)
for indexPath in indexPaths {
print("inside 1st for loop in clearSelectedLanguages, indexPaths are: \(indexPaths)")
print("languages.count in clearSelectedLanguages in languagesView os: \(languages.count)")
for language in 0..<languages.count
print("indexPath.row == language is: \(indexPath.row == language) && indexPath.section == 0 is: \(indexPath.section == 0)")
if indexPath.row == language && indexPath.section == 0 {
print("inside 2nd for loop in clearSelectedLanguages in languages")
print("languages in clearSelectedLanguages before languages.remove in languagesView are: \(languages)")
languages.remove(at: language)
print("languages in clearSelectedLanguages in languagesView are: \(languages)")
}
}
}
}
controllerData.saveLanguages(languagesToSave: languages)
languagesTable.setEditing(false, animated: true)
languagesTable.reloadData()
enableSort()
enableDelete()
}
当我要求应用程序删除(按删除按钮)字符串数组的所有元素时,它会删除除一个元素之外的所有元素。我试过以不同的顺序排列字符串数组元素,它似乎不是特定于字符串元素值的,如果它是一个 3 元素数组,它总是中间元素。
我怀疑从原始大小定义所需循环数的数组中删除元素会导致第二个 for 循环出现问题。
一些调试控制台输出:
inside 1st for loop in clearSelectedLanguages, indexPaths are: [[0, 0], [0, 1], [0, 2]]
indexPath.row == language is: true && indexPath.section == 0 is: true
inside 2nd for loop in clearSelectedLanguages in languages
languages in clearSelectedLanguages in languagesView are: ["french", "spanish", "german"]
languages in clearSelectedLanguages in languagesView are: ["spanish", "german"]
indexPath.row == language is: false && indexPath.section == 0 is: true
indexPath.row == language is: false && indexPath.section == 0 is: true
inside 1st for loop in clearSelectedLanguages, indexPaths are: [[0, 0], [0, 1], [0, 2]]
indexPath.row == language is: false && indexPath.section == 0 is: true
indexPath.row == language is: true && indexPath.section == 0 is: true
inside 2nd for loop in clearSelectedLanguages in languages
languages in clearSelectedLanguages in languagesView are: ["spanish", "german"]
languages in clearSelectedLanguages in languagesView are: ["spanish"]
inside 1st for loop in clearSelectedLanguages, indexPaths are: [[0, 0], [0, 1], [0, 2]]
indexPath.row == language is: false && indexPath.section == 0 is: true
languages in saveLanguages in dataModel are: ["spanish"]
如您所见,第二组 if 条件失败,字符串数组的最后一个元素永远不会被删除。然后程序退出所有 for 循环并调用包含最终调试打印语句的方法。
使用循环按索引删除元素常常让我们感到困惑,因为目标索引会在执行循环时发生变化。
indexPaths
为 [[0, 0], [0, 1], [0, 2]]
,languages
为 ["french", "spanish", "german"]
,
[0, 0]
对于"french"
[0, 1]
对于"spanish"
[0, 2]
对于"german"
删除第一个indexPath[0, 0]
时,可能OK:
languages in clearSelectedLanguages in languagesView are: ["french", "spanish", "german"]
languages in clearSelectedLanguages in languagesView are: ["spanish", "german"]
它删除相应的元素"french"
。
但是当删除第二个indexPath[0, 1]
时,您可能需要仔细检查输出。
languages in clearSelectedLanguages in languagesView are: ["spanish", "german"]
languages in clearSelectedLanguages in languagesView are: ["spanish"]
它删除(最初)第三个元素 "german"
而不是第二个元素 "spanish"
。因为一旦删除一个元素,数组中每个元素的索引都会改变。
因此,当您要删除第三个 indexPath [0, 2]
时,没有任何反应,因为单个元素数组 ["spanish"]
没有索引 2
.
处理这种情况的一种方法是以相反的顺序从下到上删除。
for indexPath in indexPaths.reversed() {
//...
}
但是双循环不是一种有效的方式,我会这样写:
if let indexPaths = languagesTable.indexPathsForSelectedRows {
rowCount = rowCount - (indexPaths.count)
controllerData.deleteWordsForLanguage(languages: languages, indexPaths: indexPaths)
print("indexPaths are: \(indexPaths)")
let rowsToRemove = Set(indexPaths.filter{[=13=].section == 0}.map{[=13=].row})
print("languages before filter are: \(languages)")
languages = languages.enumerated().filter{row,_ in !rowsToRemove.contains(row)}.map{}
print("languages after filter are: \(languages)")
controllerData.saveLanguages(languagesToSave: languages)
//...
}
请尝试一下。