在 Swift 中,如何检测编码的自定义类数组中的重复项?

Posted

技术标签:

【中文标题】在 Swift 中,如何检测编码的自定义类数组中的重复项?【英文标题】:In Swift, how to detect duplicates in an encoded custom class array? 【发布时间】:2016-03-22 19:41:45 【问题描述】:

我有一个数组,它存储了一个已编码的自定义类,因此可以将其保存到 NSUserDefaults。它基于带有收藏按钮的 tableView 单元格,每次按下收藏按钮时,它都会保存到本地数组,然后保存到 NSUserDefaults。问题是如果多次按下收藏按钮,该 tableView 单元格的多个副本将保存到 NSUserDefaults。这是我保存数据的代码。我尝试检查数组中是否已经存在“savedFavorite”,但由于它每次都被编码为不同的编码值,所以它看起来不像重复:

 let myDefaults = NSUserDefaults.standardUserDefaults()
  let savedShow1 = "savedShow1"
  var savedFavorite: TvShowInfo!
  var savedFavoriteArray:[TvShowInfo] = []

  @IBAction func saveShow(sender: UIButton) 

    //accessing current point of tableView Cell
    let location: CGPoint = sender.convertPoint(CGPointZero, toView: self.tvShowTableView)
    let indexPath: NSIndexPath = self.tvShowTableView.indexPathForRowAtPoint(location)!
    let searchTermsData = myDefaults.objectForKey(savedShow1) as? NSData

    //accessing previously saved info so as not to overwrite it
    if searchTermsData?.length > 0 
    let searchTermsArray = NSKeyedUnarchiver.unarchiveObjectWithData(searchTermsData!) as? [TvShowInfo]

    self.savedFavoriteArray = searchTermsArray!
    

    if searchBarActive 
      savedFavorite = filteredShowSearchResults[indexPath.row]
     else 
      savedFavorite = showArray[indexPath.row]
    

      if savedFavoriteArray.contains(savedFavorite) 
        print("Item already in array")
       else 
        savedFavoriteArray.append(savedFavorite)
   

    let savedData = NSKeyedArchiver.archivedDataWithRootObject(savedFavoriteArray)
    myDefaults.setObject(savedData, forKey: savedShow1)
    myDefaults.synchronize()
   

这是我的自定义类:

class TvShowInfo: NSObject, NSCoding 

  var poster: String
  var title: String
  var id: NSNumber

 init(poster: String, title: String, id: NSNumber) 

    self.poster = poster
    self.title = title
    self.id = id

  

  // MARK: - comply wiht NSCoding protocol

  func encodeWithCoder(aCoder: NSCoder) 
    aCoder.encodeObject(poster, forKey: "poster")
    aCoder.encodeObject(title, forKey: "title")
    aCoder.encodeObject(id, forKey: "id")
  

  required convenience init?(coder aDecoder: NSCoder) 

    // decoding could fail, for example when no Blog was saved before calling decode
    guard let unarchivedPoster = aDecoder.decodeObjectForKey("poster") as? String,
          let unarchivedTitle =  aDecoder.decodeObjectForKey("title") as? String,
          let unarchivedId = aDecoder.decodeObjectForKey("id") as? NSNumber

    else 
        // option 1 : return an default Blog
      self.init(poster: "unkown", title:"unkown", id: 0)
      return
    

    // convenience init must call the designated init
    self.init(poster: unarchivedPoster, title: unarchivedTitle, id: unarchivedId)
  

【问题讨论】:

我认为这样做的更好方法是在“不喜欢”时从数组中删除最喜欢的项......然后您只需在数组中找到匹配的一项并且删除它。 这是个好主意,问题是当您多次按下收藏按钮时,它会不断将单元格信息添加到数组中,然后才能“取消收藏”。 一种方法是保留未编码的数组的副本,然后检查它是否已被收藏。 这是被编码的自定义类,它不是自动编码的。它作为问题的一部分发布。 我可以看到你的问题............只需检查 SavedFavoriteArray 中是否存在相同的 TVShowInfo 对象,如果存在,则在您取消收藏时将其删除 【参考方案1】:

您还可以将您的数组转换为集合 (NSSet),您的数组将立即没有重复项。看到这个帖子:Set operations (union, intersection) on Swift array?

【讨论】:

没用过NSSet,怎么删除重复的? Sets 不允许重复,重复的将被自动删除。您必须记住将集合转回数组。链接中解释的所有内容。

以上是关于在 Swift 中,如何检测编码的自定义类数组中的重复项?的主要内容,如果未能解决你的问题,请参考以下文章

遍历 Swift 应用程序中的自定义 Parse 列

如何使用 NSUserDefaults 在 Swift 中存储自定义类数组?

swift Swift 4中的自定义JSON编码/解码

在 Swift 中编码对象

通过dotnet cli中的自定义模板创建类时如何检测命名空间

如何在 Swift 的自定义类中初始化 Timer? [复制]