在Swift数组

时间:2016-12-21 21:54:21

标签: arrays swift unique

我正在建立一个项目,告诉我一段文字中的独特单词。

我有我的原始字符串 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])")}

}

4 个答案:

答案 0 :(得分:4)

夫特

试试吧。

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

答案 1 :(得分: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"]

答案 2 :(得分:1)

在不保留订单的情况下过滤掉独特的单词

作为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 from this Q&A

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

答案 3 :(得分:-1)

您可以过滤数组中已包含的值:

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