我有一个coreData对象的Swift数组。对象有三个属性。我想过滤数组以删除对其中2个属性共享相同值的对象。
对象属性是object.name,object.age,object.id
所有属性都是String类型。
我想过滤数组以返回一个数组,删除了object.name和object.age相同的重复个案。
答案 0 :(得分:5)
你可以用一套:
来做var uniqueValues = Set<String>()
objectsArray = objectsArray.filter{ uniqueValues.insert("\($0.name)|\($0.age)").inserted}
您还可以通过扩展数组类型来概括该方法以涵盖其他组合:
extension Array
{
func filterDuplicate<T>(_ keyValue:(Element)->T) -> [Element]
{
var uniqueKeys = Set<String>()
return filter{uniqueKeys.insert("\(keyValue($0))").inserted}
}
}
objectsArray = objectsArray.filterDuplicate{ ($0.name,$0.age) }
答案 1 :(得分:0)
这个解决方案似乎对我有用。也许不是最优雅但足够简单。
objects是coreData对象的数组。第二个数组objectsArray是一个空数组,在嵌套迭代中使用非年龄/名称重复项填充。
var objects = [Object]()
//initialize the above array objects and fill with core data objects
objects = populateObjectsArrayWithCoreDataObjects()
//create a new empty array called objectsArray
var objectsArray = [Object]()
for index in 0..<self.objects.count {
let object = objects[index]
var isDuplicate = false
for index2 in (index + 1)..<self.objects.count {
let object2 = objects[index2]
if object.name == object2.name && object.age == object2.age {
isDuplicate = true
}
}
if isDuplicate == false {
objectsArray.append(item)
}
}
objects = objectsArray
答案 2 :(得分:0)
虽然 Alain 的解决方案非常好,但这里有一些更 swifty 的方法可以从 KeyPath s 中受益:
extension Array {
func filterDuplicates(by keyPath: PartialKeyPath<Element>) -> Self {
var uniqueKeys = Set<String>()
return self.filter { uniqueKeys.insert("\($0[keyPath: keyPath])").inserted }
}
}
现在你可以这样使用它:
yourArr.filterDuplicates(by: \YourClass.propertyName)
如果您想使用多个属性来确定唯一性,可以使用以下解决方案:
extension Array {
func withRemovedDuplicates(by keyPaths: PartialKeyPath<Element>...) -> Self {
var uniqueKeys = Set<String>()
return self.filter { element in
uniqueKeys.insert(keyPaths.map { "\(element[keyPath: $0])" }.joined()).inserted
}
}
}
使用方法如下:
yourArr.filterDuplicates(by: \YourClass.propertyOneName, \YourClass.propertyTwoName)