簡體   English   中英

在Swift數組中查找唯一值

[英]Find unique values in a Swift Array

我正在建立一個項目,告訴我一段文字中的獨特單詞。

我有我的原始字符串scriptTextView ,我已將每個單詞添加到數組scriptEachWordInArray中

我現在想創建一個名為scriptUniqueWords的數組,它只包含在scriptEachWordInArray中出現一次(換句話說是唯一的)的單詞。

所以我希望我的scriptUniqueWords數組等於= [“Silent”,“Holy”]作為結果。

我不想創建一個沒有重復項的數組,而是一個只有第一個出現一次值的數組。

var scriptTextView = "Silent Night Holy Night"
var scriptEachWordInArray = ["Silent", "night", "Holy", "night"]
var scriptUniqueWords = [String]()

for i in 0..<scriptEachWordInArray.count {

    if scriptTextView.components(separatedBy: "\(scriptEachWordInArray[i]) ").count == 1 {
        scriptUniqueWords.append(scriptEachWordInArray[i])
        print("Unique word \(scriptEachWordInArray[i])")}

}

迅速

試試吧吧。

let array = ["1", "1", "2", "2", "3", "3"]
let unique = Array(Set(array))
// ["1", "2", "3"]

您可以使用NSCountedSet

let text = "Silent Night Holy Night"
let words = text.lowercased().components(separatedBy: " ")
let countedSet = NSCountedSet(array: words)
let singleOccurrencies = countedSet.filter { countedSet.count(for: $0) == 1 }.flatMap { $0 as? String }

現在singleOccurrencies包含["holy", "silent"]

過濾掉獨特的單詞而不保留順序

作為NSCountedSet另一種替代NSCountedSet ,您可以使用字典來計算每個單詞的出現次數,並過濾掉僅出現一次的單詞:

let scriptEachWordInArray = ["Silent", "night", "Holy", "night"]

var freqs: [String: Int] = [:]
scriptEachWordInArray.forEach { freqs[$0] = (freqs[$0] ?? 0) + 1 }

let scriptUniqueWords = freqs.flatMap { $0.1 == 1 ? $0.0 : nil }
print(scriptUniqueWords) // ["Holy", "Silent"]

但是,此解決方案(以及使用NSCountedSet解決方案)不會保留原始數組的順序,因為字典以及NSCountedSet是無序集合。


在保留訂單的同時過濾掉獨特的單詞

如果您想保留原始數組中的順序(刪除多次出現的元素),您可以計算每個單詞的頻率,但將其存儲在(String, Int)元組數組而不是字典中。

利用此問答中的Collection擴展

extension Collection where Iterator.Element: Hashable {
    var frequencies: [(Iterator.Element, Int)] {
        var seen: [Iterator.Element: Int] = [:]
        var frequencies: [(Iterator.Element, Int)] = []
        forEach {
            if let idx = seen[$0] {
                frequencies[idx].1 += 1
            }
            else {
                seen[$0] = frequencies.count
                frequencies.append(($0, 1))
            }
        }
        return frequencies
    }
}

// or, briefer but worse at showing intent
extension Collection where Iterator.Element: Hashable {
    var frequencies: [(Iterator.Element, Int)] {
        var seen: [Iterator.Element: Int] = [:]
        var frequencies: [(Iterator.Element, Int)] = []
        for elem in self {
            seen[elem].map { frequencies[$0].1 += 1 } ?? {
                seen[elem] = frequencies.count
                return frequencies.append((elem, 1))
            }()
        }
        return frequencies
    }
}

...你可以過濾掉你的數組中的唯一單詞(同時保留順序)

let scriptUniqueWords = scriptEachWordInArray.frequencies
    .flatMap { $0.1 == 1 ? $0.0 : nil }

print(scriptUniqueWords) // ["Silent", "Holy"]

您可以過濾數組中已包含的值:

let newArray = array.filter { !array.contains($0) }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM