过滤swift对象数组,以删除在其一个或多个属性中具有相同值的对象

时间:2017-04-15 06:56:29

标签: ios arrays swift xcode filter

我有一个coreData对象的Swift数组。对象有三个属性。我想过滤数组以删除对其中2个属性共享相同值的对象。

对象属性是object.name,object.age,object.id

所有属性都是String类型。

我想过滤数组以返回一个数组,删除了object.name和object.age相同的重复个案。

3 个答案:

答案 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)