【问题标题】:Updating a string quantity in an array in Swift在 Swift 中更新数组中的字符串数量
【发布时间】:2017-05-21 17:08:11
【问题描述】:

假设我有一个字符串数组:

var array: [String] = ["a", "a", "b", "c", "c", "c", "d", "d"]

在数组中,我有4次a,1次b,3次c和2次d

我想将 a 的值从 4 更新为 7,并将 c 的值从 3 更新为 1。

我希望单个字符串在数组中最多出现 10 次。

我试着用这个来做:

    for _ in 0..<10 {
        if array.contains("a") {
            if let index = array.index(of: "a") {
                array.remove(at: index)
            }
        }
    }

    for _ in 0..<7 {
        array += ["a"]
    }

首先,在一个运行 10 次的循环中,我每次检查数组是否仍然包含 a,如果是,则删除它。之后,我运行了一个循环 7 次,这个循环每次都会将另一个 a 值添加到数组中,直到数组中应该有 7 个 a

这不是真正发生的事情。真正发生的是,它将数组中的所有对象替换为a,并且肯定会运行超过 7 次。

我能做些什么来解决它?

【问题讨论】:

  • 我迷失在In the array, I have 4 times "a"

标签: arrays swift string for-loop


【解决方案1】:

我建议使用字典。目前这种方法效率不高。

var dict = [
    "a": 4,
    "b": 8
]

这样您可以更新每个字母的值,而无需在数组中重复它们。要设置字典值,您可以使用下标:

dict["a"] = 2

这似乎更适合您尝试做的事情。

【讨论】:

    【解决方案2】:

    如果你想将给定元素的出现带到n,你可以写这样的东西。

    extension Array where Element == String {
    
        func updated(numOccurrencies: Int, ofWord word: String) -> [String] {
    
            let currentOccurrencies = self.filter { $0 == word }.count
            let delta = numOccurrencies - currentOccurrencies
    
            if delta > 0 {
                let newOccurrencies = Array<String>(repeatElement(word, count: delta))
                return self + newOccurrencies
            }
    
            if delta < 0 {
                var numElmsToDelete = -delta
                return filter {
                    guard $0 == word else { return true }
                    guard numElmsToDelete > 0 else { return true }
                    numElmsToDelete -= 1
                    return false
                }
            }
    
            return self
        }
    }
    

    示例

    现在给你数组

    let words = ["a", "a", "b", "c", "c", "c", "d", "d"]
    

    您可以生成一个新数组,将“a”的出现次数设置为不同的值

    words.updated(numOccurrencies: 0, ofWord: "a")
    // ["b", "c", "c", "c", "d", "d"]
    
    words.updated(numOccurrencies: 1, ofWord: "a")
    // ["a", "b", "c", "c", "c", "d", "d"]
    
    words.updated(numOccurrencies: 2, ofWord: "a")
    // ["a", "a", "b", "c", "c", "c", "d", "d"]
    
    words.updated(numOccurrencies: 3, ofWord: "a")
    // ["a", "a", "b", "c", "c", "c", "d", "d", "a"]
    
    words.updated(numOccurrencies: 4, ofWord: "a")
    // ["a", "a", "b", "c", "c", "c", "d", "d", "a", "a"]
    

    排序

    如您所见,新出现的“a”广告添加在数组末尾。如果您希望数组保持排序,只需将 .sorted() 附加到每个调用

    words.updated(numOccurrencies: 4, ofWord: "a").sorted()
    // ["a", "a", "a", "a", "b", "c", "c", "c", "d", "d"]
    

    “我希望单个字符串在数组中的最大次数为 10 次”

    我现在假设必须对输出数组进行排序。

    我将为此使用不同的方法。我将为每个单词计算我们期望该单词在输出数组中出现的次数。

    每次出现次数将是该单词的 10 次和当前出现次数之间的最小值。

    例子

    a: min(10, 2) = 2
    b: min(10, 1) = 1
    ...
    

    一旦有了每个单词的预期出现次数,我就可以从头开始构建最终的排序数组。

    extension Array where Element == String {
        func updated(withMaximumOccurrencies max: Int) -> [String] {
            let countedSet = NSCountedSet(array: self)
            let uniqueWords = Set(self)
            return uniqueWords
                .reduce([String]()) { (res, word) -> [String] in
                    let occurrencies = Swift.min(max, countedSet.count(for: word))
                    return res + [String](repeatElement(word, count: occurrencies))
                }.sorted()
        }
    }
    

    示例

    let words: [String] = ["a", "a", "b", "c", "c", "c", "d", "d"]
    
    words.updated(withMaximumOccurrencies: 1)
    ["a", "b", "c", "d"]
    
    words.updated(withMaximumOccurrencies: 2)
    ["a", "a", "b", "c", "c", "d", "d"]
    
    words.updated(withMaximumOccurrencies: 10)
    ["a", "a", "b", "c", "c", "c", "d", "d"]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 2016-07-04
      • 1970-01-01
      相关资源
      最近更新 更多