swift [duplicate]数组的唯一值

时间:2021-06-07 12:58:45

This question already has an answer here:

这个问题已经有了答案:

I'm building an iOS app with swift and i need to get all unique values of array of strings.

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

I've been reading the apple developer docs but it doesn't seem to have a function for it.

我一直在看苹果的开发者文档,但它似乎没有什么功能。

Can someone give me an hint?

谁能给我一个提示吗?

4 个解决方案

#1


101  

One way is to use a set:

一种方法是使用集合:

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

You could also create an extension that filters through the array more explicitly:

你也可以创建一个扩展来更明确地过滤数组:

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

NOTE

请注意

The unique array will be in an unspecified order, and you may need to sort it. Sometimes it's better to just do it yourself by enumerating, you could write an extension.

唯一的数组将以未指定的顺序排列,您可能需要对它进行排序。有时最好自己列举一下,你可以写一个扩展。

It might be good to make an extension (Swift 2):

可以延长(Swift 2):

extension Array where Element : Hashable {
    var unique: [Element] {
        return Array(Set(self))
    }
}

There are probably more optimized ways to do what you want, but this way is quick and easy.

可能有更优化的方法来实现您想要的,但是这种方法是快速和容易的。

#2


38  

There isn't a function to do this in the Swift standard library, but you could write one:

在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"]

This has the downside of requiring the contents of the sequence to be hashable, not just equatable, but then again most equatable things are, including strings.

这有一个缺点,要求序列的内容是可读的,不仅是可平等的,而且大多数可平等的东西都是,包括字符串。

It also preserves the original ordering unlike, say, putting the contents in a dictionary or set and then getting them back out again.

它还保留了原始的排序,不像把内容放在字典或集合中,然后再把它们取出来。

#3


3  

I don't know of a built in way. This generic function would do it:

我不知道有什么建筑方法。这个通用函数会这样做:

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
}

The downside here is that this solution runs in O(n2).

缺点是这个解在O(n2)中运行。

#4


1  

Use a dictionary like var unique = [<yourtype>:Bool]() and fill in the values like unique[<array value>] = true in a loop. Now unique.keys has what you need.

使用var unique = [ :Bool]()等字典,在循环中填入unique[ ] = true。现在唯一的。钥匙有你需要的东西。

#1


101  

One way is to use a set:

一种方法是使用集合:

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

You could also create an extension that filters through the array more explicitly:

你也可以创建一个扩展来更明确地过滤数组:

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

NOTE

请注意

The unique array will be in an unspecified order, and you may need to sort it. Sometimes it's better to just do it yourself by enumerating, you could write an extension.

唯一的数组将以未指定的顺序排列,您可能需要对它进行排序。有时最好自己列举一下,你可以写一个扩展。

It might be good to make an extension (Swift 2):

可以延长(Swift 2):

extension Array where Element : Hashable {
    var unique: [Element] {
        return Array(Set(self))
    }
}

There are probably more optimized ways to do what you want, but this way is quick and easy.

可能有更优化的方法来实现您想要的,但是这种方法是快速和容易的。

#2


38  

There isn't a function to do this in the Swift standard library, but you could write one:

在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"]

This has the downside of requiring the contents of the sequence to be hashable, not just equatable, but then again most equatable things are, including strings.

这有一个缺点,要求序列的内容是可读的,不仅是可平等的,而且大多数可平等的东西都是,包括字符串。

It also preserves the original ordering unlike, say, putting the contents in a dictionary or set and then getting them back out again.

它还保留了原始的排序,不像把内容放在字典或集合中,然后再把它们取出来。

#3


3  

I don't know of a built in way. This generic function would do it:

我不知道有什么建筑方法。这个通用函数会这样做:

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
}

The downside here is that this solution runs in O(n2).

缺点是这个解在O(n2)中运行。

#4


1  

Use a dictionary like var unique = [<yourtype>:Bool]() and fill in the values like unique[<array value>] = true in a loop. Now unique.keys has what you need.

使用var unique = [ :Bool]()等字典,在循环中填入unique[ ] = true。现在唯一的。钥匙有你需要的东西。