比较 Swift 中的两个对象数组

Comparing two arrays of objects in Swift

我有两个不同大小的对象数组。 第一个是旧数据,第二个是来自服务器的更新数据(包括旧数据和新数据),数据可以混合。我想了解这些数组之间的区别。

我的class

class Station {
  var dateOfIssue: Date
  var region: String
  var locality: String
  var bsName: String
  var freqIn: String
  var freqOut: String
  var networkType: String
  var provider: String
  var bsUsableName: String
  ...
}

我要比较的数组(示例)

var a = [Station]()
var b = [Station]()
for _ in 0...5 {      
  a.append(Station(someRandomStationValue...)
}
b = a
for _ in 0...7{
  b.append(Station(someRandomStationValue...)  //array "b" will contain all that array "a" contains and some new values
}

如何比较这些数组,比较它们之间的所有字段并获得具有差异的新数组(如 java:b.removeAll(a))?

正如 koropok 评论中提到的,您可以使用 subtract 方法:

// Added to make original code functional 
// Station must conform to Hashable protocol in order to be stored in the Set
struct Station: Hashable {
    let id: Int
}

var a = [Station]()
for i in 0...5 {
    a.append(Station(id:i))
}

var b = [Station]()
for i in 0...7{
    //array "b" will contain all that array "a" contains and some new values
    b.append(Station(id:i))  
}

var c = Set(b)

// c will contain 6 and 7
c.subtract(a)

正如@koropok 所指出的,一个好的解决方案是使用Set。第一步是使您的类型符合 Hashable。对于 类,您必须实现 ==hash(into:) 函数,但如果您使用 struct,则除了声明一致性外,您无需执行任何其他操作。所以:

struct Station: Hashable {
  var dateOfIssue: Date
  var region: String
  ...
}

现在您应该可以将 Station 添加到 Set 中了。因此:

var a = Set<Station>()
for _ in 0...5 {
  a.insert(Station(...))
}
var b = Set<Station>()
a.forEach { b.insert([=11=]) }
for _ in 0...7 {
  b.insert(Station(...))
}

let c = b.subtracting(a)

Set 还提供了一个方便的初始化程序,您可以使用它来将 Station 数组转换为集合:

let s = Set(arrayLiteral: [your, station, objects])

您可以使用 Set,它提供了内置的 .subtract().subtracting() 方法,可以删除 Sets[=17= 中的公共条目]

struct Station: Hashable,CustomStringConvertible {
    var id: Int
    var region: String
    var locality: String
    var bsName: String

    // Just to provide a pretty print statement
    var description: String {
        return "ID: \(id) | region: \(region) | locality: \(locality) | bsName: \(bsName)"
    }
}

var stations1 = Set<Station>()
var stations2 = Set<Station>()

for currentNumber in 0...3 {
    stations1.insert(Station(id: currentNumber, region: "abc", locality: "abc", bsName: "abc"))
}

for currentNumber in 0...5 {
    stations2.insert(Station(id: currentNumber, region: "abc", locality: "abc", bsName: "abc"))
}

// Caluculating the difference here
print(stations2.subtracting(stations1))