【问题标题】:Unique values of array in swift [duplicate]swift中数组的唯一值[重复]
【发布时间】:2014-12-23 16:32:01
【问题描述】:

我正在使用 swift 构建一个 iOS 应用程序,我需要获取字符串数组的所有唯一值。

我一直在阅读苹果开发者文档,但它似乎没有相应的功能。

谁能给我一个提示?

【问题讨论】:

标签: ios swift


【解决方案1】:

可能有更有效的方法,但扩展可能是最直接的:

extension Array where Element: Equatable {
    var unique: [Element] {
        var uniqueValues: [Element] = []
        forEach { item in
            guard !uniqueValues.contains(item) else { return }
            uniqueValues.append(item)
        }
        return uniqueValues
    }
}

如果顺序无关紧要并且对象也是可散列的:

let array = ["one", "one", "two", "two", "three", "three"]
// order NOT guaranteed
let unique = Array(Set(array))
// ["three", "one", "two"]

【讨论】:

  • 第一个例子简洁明了。在 Swift 3 中工作。谢谢!
  • Array(Set()) 也适用于 Swift 4。很好的解决方案。谢谢。
  • 看看这个解决方案stackoverflow.com/a/48210756/5790492
  • 否定。使用 set 可以得到随机顺序。
  • @BB9z 我在答案中指出了这一点,并且还提供了一个可以保持秩序的扩展,所以不知道你想要什么:)
【解决方案2】:

在 Swift 标准库中没有执行此操作的函数,但您可以编写一个:

extension Sequence where Iterator.Element: Hashable {
    func unique() -> [Iterator.Element] {
        var seen: [Iterator.Element: Bool] = [:]
        return self.filter { seen.updateValue(true, forKey: $0) == nil }
    }
}

let a = ["four","one", "two", "one", "three","four", "four"]
a.unique // ["four", "one", "two", "three"]

这有一个缺点,即要求序列的内容是可散列的,不仅仅是可等价的,而且大多数可等价的东西也是如此,包括字符串。

它还保留了原始顺序,这与将内容放入字典或集合然后再将它们放回原处不同。

【讨论】:

  • 有错误吗? `使用未解析的标识符'seq'`
  • 啊,原来如此,应该是filter(source)
  • 对于我的应用程序,这种方法至少比 distinct 快约 3 倍。
  • 这会在 Swift 2 中引发错误。它应该是 source.filter
  • 不适用于 Swift 3。你有什么想法吗?
【解决方案3】:

我不知道内置的方式。这个通用函数可以做到:

func distinct<S: SequenceType, E: Equatable where E==S.Generator.Element>(source: S) -> [E]
{
    var unique = [E]()

    for item in source
    {
        if !contains(unique, item)
        {
            unique.append(item)
        }
    }
    return unique
}

这里的缺点是这个解决方案在 O(n2) 中运行。

【讨论】:

  • contains 在 O(n) 中运行,因此该解决方案在二次时间中运行(尽管它确实具有不需要元素可散列的好处)。
  • @AirspeedVelocity 是的,这很好。并且可散列通常不会像您在解决方案中指出的那样成为问题。尽管如此,如果必须是可散列的,它是一个替代的解决方案,虽然速度较慢,这是一个游戏破坏者。我更喜欢你的解决方案,但我想我会因为这个原因而保持发布。
  • 重载意味着你可以同时实现这两者,并且会选择最好的! (因为 Hashable 符合 Equatable,所以更具体,重载决议会更喜欢它:)
  • (只要你让两个版本都采用序列或数组,那就是......否则他们会打架)
  • 是的!一定要喜欢 Swift :) 我将编辑我的答案以使序列更通用,以防万一有人想采用重载方法。
【解决方案4】:

使用var unique = [&lt;yourtype&gt;:Bool]() 之类的字典,并在循环中填写unique[&lt;array value&gt;] = true 之类的值。现在unique.keys 有你需要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 2017-05-07
    • 2012-06-30
    • 1970-01-01
    • 2017-09-08
    • 2020-09-20
    • 1970-01-01
    • 2016-11-07
    相关资源
    最近更新 更多