在 Swift 中向数组追加唯一的值

19

我在Swift中没有找到任何关于此的内容。找到了如何在数组中找到唯一值,但不是这个。如果听起来相当基础,请见谅...

但我有以下数组

var selectedValues = [String]()

并且下一个值来自于Parse查询。

 var objectToAppend = object.objectForKey("description")! as! String

这是目前我正在做的方式。

self.selectedHobbies.append(objectToAppend)

但由于查询发生了多次,最终追加了重复的值。虽然它可以工作,但我只想避免浪费内存并保留唯一值。

有什么方法可以在 Swift 中解决这个问题吗?

2个回答

33
您可以使用 Set 来保证数值的唯一性。
var selectedValues = Set<String>()
// ...
selectedValues.insert(newString) // will do nothing if value exists

当然,Set的元素是无序的。

如果您想保留顺序,请继续使用Array,但在插入之前进行检查。

if !selectedValues.contains("Bar") { selectedValues.append("Bar") }

能否保持代码语法,但使用[String]代替Set<String>?对我来说,Set<String>没有太多用处,因为我可以将其转换为[String]。我尝试了很多次,但没有什么好运气。 - GuiSoySauce
@Mundi,你不需要进行contains检查。如果你执行insert操作,而元素已经存在,什么也不会发生。 - Alexander
@Alexander 同意。已更改。 - Mundi
当你只需要唯一值时,你也可以忽略你放入数组中的内容,直接使用.unique。在某些情况下,这可能更可取,比如唯一性检查很耗费时间,而保存数据则不是。 - kevin
Set 仅适用于可哈希类型。例如,Set<String> 可行,但 Set<SomeProtocol> 不行。 - Gargo

9
我猜您的问题已经解决了,但我会为下一个遇到同样问题的开发人员添加我的答案 :)
我的解决方案是编写一个Array的扩展,以不同的方式添加数组元素:
以下是代码:
extension Array{
    public mutating func appendDistinct<S>(contentsOf newElements: S, where condition:@escaping (Element, Element) -> Bool) where S : Sequence, Element == S.Element {
      newElements.forEach { (item) in
        if !(self.contains(where: { (selfItem) -> Bool in
            return !condition(selfItem, item)
        })) {
            self.append(item)
        }
    }
  }
}

例子:

var accounts: [Account]
let arrayToAppend: [Account]
accounts.appendDistinct(contentsOf: arrayToAppend, where: { (account1, account2) -> Bool in
        return account1.number != account2.number
})

嗨,我有一个问题。我把你的代码定制成了这样:public mutating func appendDistinct<T>(_ newElement: T, where condition: @escaping (Element) -> Bool) where T == Element { if !(self.contains(where: { (newElement) -> Bool in return !condition(newElement) })) { self.append(newElement) } }然而,它显示了一个警告:"同类型要求使得泛型参数'T'和'Element'等效;这在Swift 6中是一个错误。"我该如何解决这个问题并获得正确的代码? - undefined
嗨 @Kaaaaai,我认为在这种情况下,我们不需要在这个方法中使用泛型类型。 这个方法可以简单地写成这样:public mutating func appendDistinct(_ newElement: Element, where condition: @escaping (Element) -> Bool) { if !(self.contains(where: { (newElement) -> Bool in return !condition(newElement) })) { self.append(newElement) } } - undefined
太有帮助了,谢谢~ - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接