我可能有一个像下面这样的数组:

[1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]

或者,实际上,任何类似类型的数据部分的序列。我要做的是确保每个相同的元素只有一个。例如,上面的数组将变成:

[1, 4, 2, 6, 24, 15, 60]

请注意,删除了2、6和15的重复项,以确保每个相同的元素中只有一个。Swift是否提供了一种容易做到这一点的方法,还是我必须自己做?


当前回答

var numbers = [1,2,3,4,5,10,10, 12, 12, 6,6,6,7,8,8, 8, 8, 8 , 7 , 1 , 1, 2 , 9]

var newArr : [Int] = []
for n in numbers {
    if !newArr.contains(n) {
        newArr.append(n)
    }
}

输出- [1,2,3,4,5,10,12,6,7,8,9]

上面的解决方案保持了顺序,但是很慢,因为.contains一次又一次地迭代。 因此使用有序集。

这将打印有序数组。

Array(NSOrderedSet.init(array: numbers))

输出- [1,2,3,4,5,10,12,6,7,8,9]

这将打印一个无序数组。

let uniqueUnordered = Array(Set(numbers))

输出- [4,2,1,9,10,3,5,6,8,12,7]

其他回答

这在Swift 4中是有效的,如果你不想/需要将结果转换为数组,但可以使用Set。默认情况下,结果没有排序,但是可以使用sorted()这样做,它返回一个数组,如print语句所示。

let array = [1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]

var result = Set<Int>()
_ = array.map{ result.insert($0) }

print(result.sorted())  // [1, 2, 4, 6, 15, 24, 60]

你可以自己卷,比如这样:

func unique<S : Sequence, T : Hashable>(source: S) -> [T] where S.Iterator.Element == T {
    var buffer = [T]()
    var added = Set<T>()
    for elem in source {
        if !added.contains(elem) {
            buffer.append(elem)
            added.insert(elem)
        }
    }
    return buffer
}

let vals = [1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]
let uniqueVals = uniq(vals) // [1, 4, 2, 6, 24, 15, 60]

作为Array的扩展:

extension Array where Element: Hashable {
    func uniqued() -> Array {
        var buffer = Array()
        var added = Set<Element>()
        for elem in self {
            if !added.contains(elem) {
                buffer.append(elem)
                added.insert(elem)
            }
        }
        return buffer
    }
}

或者更优雅一点(Swift 4/5):

extension Sequence where Element: Hashable {
    func uniqued() -> [Element] {
        var set = Set<Element>()
        return filter { set.insert($0).inserted }
    }
}

将被使用:

[1,2,4,2,1].uniqued()  // => [1,2,4]

首先将数组的所有元素添加到NSOrderedSet中。 这将删除数组中的所有重复项。 再次将这个orderedset转换为一个数组。

做……

例子

let array = [1,1,1,1,2,2,2,2,4,6,8]

let orderedSet : NSOrderedSet = NSOrderedSet(array: array)

let arrayWithoutDuplicates : NSArray = orderedSet.array as NSArray

输出arraywithoutduplates - [1,2,4,6,8]

Swift 3/ Swift 4/ Swift 5

只需要一行代码就可以省略数组副本而不影响顺序:

let filteredArr = Array(NSOrderedSet(array: yourArray))
var numbers = [1,2,3,4,5,10,10, 12, 12, 6,6,6,7,8,8, 8, 8, 8 , 7 , 1 , 1, 2 , 9]

var newArr : [Int] = []
for n in numbers {
    if !newArr.contains(n) {
        newArr.append(n)
    }
}

输出- [1,2,3,4,5,10,12,6,7,8,9]

上面的解决方案保持了顺序,但是很慢,因为.contains一次又一次地迭代。 因此使用有序集。

这将打印有序数组。

Array(NSOrderedSet.init(array: numbers))

输出- [1,2,3,4,5,10,12,6,7,8,9]

这将打印一个无序数组。

let uniqueUnordered = Array(Set(numbers))

输出- [4,2,1,9,10,3,5,6,8,12,7]