从数组中删除重复的 PHAssets?

Removing duplicate PHAssets from an array?

我正在使用名为 BSImagePicker 的第三方库从照片库中 select 多张图片。我可以将最大 PHAssets 设置为 selected,但是当我显示 BSImagePickerController 以选择更多照片时,问题就来了。那些 PHAssets 只是另外添加到 selectedAssets 并且实际上复制了图像。我尝试使用删除重复项 PHAsset 和图像,但它不起作用:

extension Array where Element: Equatable {
mutating func removeDuplicates() {
    var result = [Element]()
    for value in self {
        if !result.contains(value) {
            result.append(value)
        }
    }
    self = result
   }
}

func presentBSImagePickerController(vc: BSImagePickerViewController) {
        self.bs_presentImagePickerController(vc, animated: true,
                                             select: { (asset: PHAsset) -> Void in

        }, deselect: { (asset: PHAsset) -> Void in
            // User deselected an assets.

        }, cancel: { (assets: [PHAsset]) -> Void in
            // User cancelled. And this where the assets currently selected.

        }, finish: { (assets: [PHAsset]) -> Void in


            // User finished with these assets

            for i in 0..<assets.count  {
                self.selectedAssets.append(assets[i])
            }
            self.selectedAssets.removeDuplicates()

            self.convertAssetToImages()

        }, completion: nil)
    }

    func convertAssetToImages() -> Void {

        if selectedAssets.count != 0 {

            for i in 0..<selectedAssets.count {

                let manager = PHImageManager.default()
                let option = PHImageRequestOptions()
                var thumbnail = UIImage()
                option.isSynchronous = true

                manager.requestImage(for: selectedAssets[i], targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: option, resultHandler: {(result, info)->Void in
                    thumbnail = result!

                })

                let data = UIImageJPEGRepresentation(thumbnail, 0.7)
                let newImage = UIImage(data: data!)

                self.photosArray.append(newImage! as UIImage)
                self.photosArray.removeDuplicates()
                print(self.photosArray.removeDuplicates())

                DispatchQueue.main.async {
                    self.collectionView.reloadData() // reloads the collection view on main thread
                }
            }
        }
    }

的问题
for i in 0..<assets.count  {
    self.selectedAssets.append(assets[i])
}
self.selectedAssets.removeDuplicates()

...是您的 removeDuplicates(除了慢得无法忍受!)只是假设 PHAsset 相等是重复图像的标记。它不是。资产只是图书馆中内容的临时代表。您想要知道的是资产的 本地标识符 是否与您已有的资产匹配。我建议这样做:

var ids = Set(self.selectedAssets.map {[=11=].localIdentifier})
for asset in assets  {
    if !ids.contains(asset.localIdentifier) {
        ids.insert(asset.localIdentifier)
        self.selectedAssets.append(asset)
    }
}

我们列出了我们已有资产的所有本地标识符。然后,仅当其标识符不在列表中时,我们才附加资产(及其标识符)。这将 快(因为 Set contains 比 Array contains 快得多),并且还应防止 "the same photo" 出现两次。

步骤:1. 这段代码应该足够了:

extension Array where Element: Equatable {
mutating func removeDuplicates() {
    var result = [Element]()
    for value in self {
        if !result.contains(value) {
            result.append(value)
        }
    }
    self = result
}

}

步骤: 2. "selectedAssets"是PHAssets类型数组,你必须从"selectedAssets"数组中删除所有资产。因为你显示的是来自 "photosArray" 的 multiImage,这个数组总是有你的图像,而 "selectedAssets" 数组在删除后总是有参考价值。因此,在 for 循环之前从 "selectedAssets" 数组中删除所有资产,如下所示。或者,如果您有任何疑问,请随时向我提问(Mohit Tomer)

// MARK:- Selecting Multiple Image From Gallery.
func showingImagePicker() {
    let vc = BSImagePickerViewController()
    var ids = Set(self.selectedAssets.map {[=11=].localIdentifier})
    vc.maxNumberOfSelections = 5
    vc.cancelButton.tintColor = UIColor.red
    vc.selectionCharacter = "✓"

    self.bs_presentImagePickerController(vc, animated: true, select: { (asset: PHAsset) -> Void in
        print("Selected: \(asset)")
    }, deselect: { (asset: PHAsset) -> Void in
        print("Deselected: \(asset)")
    }, cancel: { (assets: [PHAsset]) -> Void in
        print("Cancel: \(assets)")
    }, finish: { (assets: [PHAsset]) -> Void in
        print("Finish: \(assets)")

        self.selectedAssets.removeAll()
        for asset in assets  {
            if !ids.contains(asset.localIdentifier) {
                ids.insert(asset.localIdentifier)
                self.selectedAssets.append(asset)
            }
        }
        self.convertingAssetToImage()

    }, completion: nil)
}




    func convertingAssetToImage() -> Void {
    var thumbnail = UIImage()
    if selectedAssets.count != 0 {

        for item in selectedAssets {
            let manager = PHImageManager.default()
            let option = PHImageRequestOptions()
            option.isSynchronous = true
            manager.requestImage(for: item, targetSize: CGSize(width: 200.0, height: 200.0), contentMode: .aspectFill, options: option, resultHandler: { (result, info) -> Void in
                print("result", result as Any)
                print("info", info as Any)
                thumbnail = result!
            })

            self.photoArray.append(thumbnail)
            self.photoDataArray.append(thumbnail.jpegData(compressionQuality: 0.5))

        }

    }
}