如果我有结构,请说:
struct Subject {
var subjectID: String?
var name: String?
var note: String?
}
我有两个具有这种结构的数组:Array1和Array2。
例如:
Array1 = [(subjectID = "T", name = "H", note = "DF"), (subjectID = "F", name = "H", note = "SD")]
Array2 = [(subjectID = "T", name "G", note = "DF"), (subjectID = "R", name = "F", note = "SDF")]
我要返回一个新数组,该数组由Array2
中与subjectID
的{{1}}字段匹配但具有不同{ {1}}和/或Array1
元素。
在上面的示例中,返回的数组为:
name
因为它包含与note
中相同的[(subjectID = "T", name "G", note = "DF")]
(在本例中为subjectID
),但是T
字段不同。请注意,此新返回数组的字段应为Array1
中的原始值(例如:您无需更正它们以匹配name
)
是否有一种简单的方法(例如:一两行代码)来执行此操作而不用强行强制执行它?
谢谢!
答案 0 :(得分:2)
这里有很好的答案,我宁愿保持测试简单。
首先设置
struct Subject {
var subjectID: String?
var name: String?
var note: String?
}
let array1 = [Subject(subjectID: "T", name: "H", note: "DF"), Subject(subjectID: "F", name: "H", note: "SD")]
let array2 = [Subject(subjectID: "T", name: "G", note: "DF"), Subject(subjectID: "R", name: "F", note: "SDF")]
现在让我们看一下实际算法。 array2.filter
返回Subject
中array2
的数组,其中该块返回true
。如果array1.contains
中的true
中的任何Subject
返回array1
,则true
返回let result = array2.filter { s2 in
array1.contains { s1 in
s1.subjectID == s2.subjectID && (s1.name != s2.name || s1.note != s2.note)
}
}
。测试本身就是您所描述的。主题ID是否相等,名称或注释是否相同?
<thread>
答案 1 :(得分:0)
您可以这样做:
let subjectsByID = Dictionary(grouping: array1, by: { $0.subjectID })
let diff = array2.filter { subject in
if let other = subjectsByID[subject.subjectID]?.first {
return subject.name != other.name || subject.note != other.note
} else {
return false
}
}
它将按ID对第一个数组中的主题进行分组,然后根据是否有该ID的条目使用不同的名称或注释来过滤第二个数组。您没有指定在第一个数组中有多个具有相同ID的条目时要怎么做,因此它只会查看第一个。
答案 2 :(得分:0)
您可以根据第一个数组元素过滤第二个数组元素,例如:
let Array1 = [Subject(subjectID: "T", name: "H", note: "DF"), Subject(subjectID: "F", name: "H", note: "SD")]
let Array2 = [Subject(subjectID: "T", name: "G", note: "DF"), Subject(subjectID: "R", name: "F", note: "SDF")]
let result = Array2.filter { subject -> Bool in
for s in Array1 {
if subject.subjectID == s.subjectID && subject.name != s.name && subject.note != s.subjectID { return true }
}
return false
}
result
应包含您的要求。请记住,它具有嵌套迭代(O(n²)
)的复杂性。
答案 3 :(得分:0)
我结合使用了forEach和filter来查找所需的元素
var result = [Subject]()
arr1.forEach( { subject in
result.append(contentsOf: arr2.filter( { $0.subjectID == subject.subjectID &&
($0.name != subject.name ||
$0.note != subject.note) }))
})
要获得更简洁的代码,可以在struct中对函数进行检查
struct Subject {
...
func isModifiedComparedTo(_ subject: Subject) -> Bool {
return self.subjectID == subject.subjectID && (self.name != subject.name || self.note != subject.note)
}
}
var result = [Subject]()
arr1.forEach( { subject in
result.append(contentsOf: arr2.filter({$0.isModifiedComparedTo(subject)}))
})