在Swift 5中从数组中删除重复的对象

问题描述

我有一系列问题,每个问题都有一个唯一的lineID。 问题是,有时我会同步服务器中的问题(1000次同步中有1次),所以问题重复了。我有56个问题,而不是28个问题。 我想以某种方式过滤问题数组,如果有2个问题具有相同的lineID(重复项),则仅将1个附加到我的对象数组中。 谁能帮我解决这个问题?

// Get the questions from CoreData.
  func loadQuestionsUsing(templateId: Int) {
     
    do {
      guard let questions = try Question.getQuestions(templateId: templateId,context: context) else { return }
       
      checklistSections = []
       
      questions.forEach { question in
         
        // If the question lineID is duplicated,then select only one of that 2 duplications.
         
        // code here
         
        print(“Question Line ID: \(question.lineId)“)
         
        // If the question have the same templateID as the Checklist Template which user selected from the menu then create an object with that question properties.
        if question.templateId == templateId {
           
          let showVehicle = question.vehicle == 1
          let showTrailer = question.trailer == 1
          let highlight = question.highlight == 1
          let pg9 = question.pg9 == 1
          let question = ChecklistQuestion( rowID: Int(question.id),templateID: Int(question.templateId),lineID: Int(question.lineId),poolID: Int(question.poolId),descript: question.descript ?? String(),showVehicle: showVehicle,showTrailer: showTrailer,header: question.header ?? String(),highlight: highlight,pg9: pg9,imagesPath: [])
          let header = (question.header.isEmpty) ? Constants.questionsNoHeader : question.header
           
          // check if question.header (Section) exist in the ChecklistItemSection
          if let existingSection = checklistSections.firstIndex(where: { $0.name == header }) {
             
            // If section exist then append the ChecklistItem (question) to that existing section.
            checklistSections[existingSection].questions.append(question)
          } else {
            // If section don’t exist then create the section (question.header) and also append the question to that section.
            checklistSections.append(ChecklistSection(name: header,questions: [question]))
          }
        }
      }

    } catch {
      print(“Error while fetching the Questions from CoreData: \(error.localizedDescription)“)
    }
     
    print(“CHECKLIST CONTAINS: \(checklistSections.count) Sections.“)
  }

ChecklistSection的结构:

class ChecklistSection {

    var name: String                            // Name of the section
    var questions: [ChecklistQuestion]          // List with all questions from a Section
    
    init(name: String,questions: [ChecklistQuestion]) {

        self.name = name
        self.questions = questions
    }
}

我的愚蠢解决方案:

func findDuplicatedQuestions(checklistSections: [ChecklistSection]) -> [ChecklistSection] {
        
        var duplicates: [ChecklistQuestion] = []
        
        var prevQuestionLineID: Int = 0
        var addedQuestionLineID: Int = 0
        
        checklistSections.forEach { section in
            section.questions.forEach { question in
                if (prevQuestionLineID == question.lineId && addedQuestionLineID != question.lineId) {
                    duplicates.append(question)
                    addedQuestionLineID = question.lineId
                }
                
                prevQuestionLineID = question.lineId
            }
        }
        
        return checklistSections
    }

感谢阅读!

解决方法

将您的ChecklistQuestion转换为Equatable,实现==,以便知道如何比较两个实例。

class ChecklistQuestion: Equatable {
static func ==(lhs: ChecklistQuestion,rhs: ChecklistQuestion) -> Bool {
return lhs.lineID == rhs.lineID
}
}

然后使用此扩展程序删除重复的项目:

extension Array where Element: Equatable {
    
    /// Remove Duplicates
    var unique: [Element] {
        // Thanks to https://github.com/sairamkotha for improving the method
        return self.reduce([]){ $0.contains($1) ? $0 : $0 + [$1] }
    }
}

用法:

var questions: [ChecklistQuestion] = ...
questions.unique
//or 
var uniqueQuestions = questions.unique

扩展积分为https://github.com/dillidon/alerts-and-pickers

,

如果您需要保留顺序并仍然使用数组(并以O(n)运行)。使用这个:

func getUnique(questions: [ChecklistQuestion]) -> [ChecklistQuestion] {
   var set = Set<ChecklistQuestion>()
   var res = [ChecklistQuestion]()

   for question in questions {
     if !set.contains(question) {
         res.append(question)
         set.insert(question)
     }
    }

   return res
}

您需要为模型实现Hashable协议