从筛选器列表以及原始列表中删除项目

时间:2018-03-11 17:03:11

标签: ios swift uitableview uisearchbar

我正在UISearchBar Swift 4.0上工作。我有originalList[ModelItem]filterList[ModelItem]。在搜索时可以说用户想要删除filterList第5个位置,这是实际originalList上的第10个项目。从列表中删除这个项目是否有意义?项目没有id或类似的类型字段。

这种双向删除的基本步骤是什么?我一直在寻找实现这一目标的一般想法。

2 个答案:

答案 0 :(得分:1)

如果模型是一个类,并且filterList是直接从originalList创建的(没有创建新对象,但两个列表都引用相同的对象),那么您可以使用以下代码:

let itemToDelete = filterList.remove(at: indexPath.row)
if let index = originalList.index(where: { $0 === itemToDelete }) {
    originalList.remove(at: index)
}
print(originalList)
print(filterList)

===运算符将测试实例的相等性,从而确定要从originalList中删除的正确实例。

如果您使用struct作为模型,则必须使用一些启发式实现Equatable,即使没有明确的标识符,也能检测两个实例是否相等。然后使用==originalList中找到要删除的正确实例。

另一个替代方案可能是使用索引方法实现搜索,它将使用与当前过滤方法相同的过滤算法,但会再使用一个参数 - filterListfilterIndex)中的索引以及过滤器文本,并基于此计算并返回originalList中与提供的过滤器文本对和filterIndex匹配的索引。

另一种替代方案,我不建议(我称之为黑客) - 您可以保留从originalListfilterList的索引字典,您可以使用这些字典在{ {1}}和originalList。然而,这将要求您始终更新该字典,无论对其中一个列表进行任何更改 - 每次搜索,每次删除或删除或插入都需要更新映射字典。这似乎是复杂和容易出错的方法。

答案 1 :(得分:1)

您有很多选择。

  • 您可以维护原始位置和已过滤项目位置之间的映射,以便在两个列表上执行删除。
  • 您可以识别您的商品,这样您就可以搜索原始列表中的相应商品并将其删除。请注意,可以测试所有引用类型的身份(===)。
  • 您可以使用已过滤的"视图"到原始列表,而不是过滤后的副本,因此删除将自然地在原始列表上执行。

我认为我们没有针对后一种选择的标准解决方案,这使得这种方法变得最复杂。

当选择前两个选项中的任何一个时,请小心操作过滤后的副本时可能发生的原始列表更新。