【问题标题】:Swift4. Dictionaries merging斯威夫特4。字典合并
【发布时间】:2019-08-02 22:10:33
【问题描述】:

有问题。有两个具有相同键的字典。我需要连接它们以从每个字典中随机获取一半的值。

提前感谢您的回答。

var hiraganaDictionary1 = [
"a":"あ", "i":"い", "u":"う", "e":"え", "o":"お",
"A":"あ", "I":"い", "U":"う", "E":"え", "O":"お",
"ka":"か", "ki":"き", "ku":"く", "ke":"け", "ko":"こ",
"Ka":"か", "Ki":"き", "Ku":"く", "Ke":"け", "Ko":"こ",
"sa":"さ", "shi":"し", "su":"す", "se":"せ", "so":"そ",
"Sa":"さ", "Shi":"し", "Su":"す", "Se":"せ", "So":"そ",
"ta":"た", "chi":"ち", "tsu":"つ", "te":"て", "to":"と",
"Ta":"た", "Chi":"ち", "Tsu":"つ", "Te":"て", "To":"と",
"na":"な", "ni":"に", "nu":"ぬ", "ne":"ね", "no":"の",
"Na":"な", "Ni":"に", "Nu":"ぬ", "Ne":"ね", "No":"の"]


var katakanaDictionary1 = [
"a":"ア", "i":"イ", "u":"ウ", "e":"エ", "o":"オ",
"A":"ア", "I":"イ", "U":"ウ", "E":"エ", "O":"オ",
"ka":"カ", "ki":"キ", "ku":"ク", "ke":"ケ", "ko":"コ",
"Ka":"カ", "Ki":"キ", "Ku":"ク", "Ke":"ケ", "Ko":"コ",
"sa":"サ", "shi":"シ", "su":"ス", "se":"セ", "so":"ソ",
"Sa":"サ", "Shi":"シ", "Su":"ス", "Se":"セ", "So":"ソ",
"ta":"ソ", "chi":"チ", "tsu":"ツ", "te":"テ", "to":"ト",
"Ta":"ソ", "Chi":"チ", "Tsu":"ツ", "Te":"テ", "To":"ト",
"na":"ナ", "ni":"ニ", "nu":"ヌ", "ne":"ネ", "no":"ノ",
"Na":"ナ", "Ni":"ニ", "Nu":"ヌ", "Ne":"ネ", "No":"ノ" ]

【问题讨论】:

标签: swift dictionary random swift4


【解决方案1】:

merging(_:uniquingKeysWith:) 采用一个函数来决定如何处理冲突。您可以使用该功能在字典之间随机选择。

let merged = hiraganaDictionary1.merging(katakanaDictionary1,
                                         uniquingKeysWith: { first, second in
                                            Bool.random() ? first : second })

【讨论】:

    【解决方案2】:
    let hiraganaDictionary1 = [
        "a":"あ", "i":"い", "u":"う", "e":"え", "o":"お",
        "A":"あ", "I":"い", "U":"う", "E":"え", "O":"お",
        "ka":"か", "ki":"き", "ku":"く", "ke":"け", "ko":"こ",
        "Ka":"か", "Ki":"き", "Ku":"く", "Ke":"け", "Ko":"こ",
        "sa":"さ", "shi":"し", "su":"す", "se":"せ", "so":"そ",
        "Sa":"さ", "Shi":"し", "Su":"す", "Se":"せ", "So":"そ",
        "ta":"た", "chi":"ち", "tsu":"つ", "te":"て", "to":"と",
        "Ta":"た", "Chi":"ち", "Tsu":"つ", "Te":"て", "To":"と",
        "na":"な", "ni":"に", "nu":"ぬ", "ne":"ね", "no":"の",
        "Na":"な", "Ni":"に", "Nu":"ぬ", "Ne":"ね", "No":"の"]
    
    
    let katakanaDictionary1 = [
        "a":"ア", "i":"イ", "u":"ウ", "e":"エ", "o":"オ",
        "A":"ア", "I":"イ", "U":"ウ", "E":"エ", "O":"オ",
        "ka":"カ", "ki":"キ", "ku":"ク", "ke":"ケ", "ko":"コ",
        "Ka":"カ", "Ki":"キ", "Ku":"ク", "Ke":"ケ", "Ko":"コ",
        "sa":"サ", "shi":"シ", "su":"ス", "se":"セ", "so":"ソ",
        "Sa":"サ", "Shi":"シ", "Su":"ス", "Se":"セ", "So":"ソ",
        "ta":"ソ", "chi":"チ", "tsu":"ツ", "te":"テ", "to":"ト",
        "Ta":"ソ", "Chi":"チ", "Tsu":"ツ", "Te":"テ", "To":"ト",
        "na":"ナ", "ni":"ニ", "nu":"ヌ", "ne":"ネ", "no":"ノ",
        "Na":"ナ", "Ni":"ニ", "Nu":"ヌ", "Ne":"ネ", "No":"ノ" ]
    
    var mixed = hiraganaDictionary1
    for (key, _) in hiraganaDictionary1 {
        if Bool.random() {
            if let value = katakanaDictionary1[key] {
                mixed[key] = value
            }
        }
    }
    

    【讨论】:

    • 最好使用.merging(…) 方法,而不是只循环一个字典。
    • @user28434 由 Rob 完成 :-)。如果由于某种原因该键在两个字典中都不存在,则该值会丢失……最糟糕的是,它会随机丢失。
    • 好吧,当我写那条评论时,Rob Napier 的回答完全不同。
    • 是的,我最初误解了这个问题,并写了关于合并两个半字典的内容。我错过了钥匙应该是相同的这一点(我在考虑两组独立的钥匙)。
    【解决方案3】:

    由于您希望每个现有键都有一个值,您可以使用 Bool.random 来确定从哪个字典中选择值

    var combined = [String:String]()
    hiraganaDictionary1.keys.makeIterator().forEach {
        combined[$0] = Bool.random() ? hiraganaDictionary1[$0] : katakanaDictionary1 [$0]
    }
    

    这里有一个替代方案,每隔一圈使用Bool.random(),每隔一圈使用与上一次调用Bool.random()相反的内容,这将从每个字典中抽取50%

    var combined = [String:String]()
    var flag = true
    var randomFlag: Bool
    hiraganaDictionary1.keys.makeIterator().forEach {
        if (!flag) {
            combined[$0] = !randomFlag ? hiraganaDictionary1[$0] : katakanaDictionary1 [$0]
        } else {
            randomFlag =  Bool.random()
            combined[$0] = randomFlag ? hiraganaDictionary1[$0] : katakanaDictionary1 [$0]
        }
        flag = !flag
    }
    

    【讨论】:

      【解决方案4】:

      Bool.random() 不保证一半的键来自每个字典。作为一个简单的测试:

      var bool = Bool.random()
      var count = 0
      for _ in 1...100 {
          if bool { count += 1 }
          bool = Bool.random()
      }
      
      print(count)
      

      这可能会在多次运行时产生53, 61, 57, ...

      如果您想确保“从每个字典中随机获取 half 中的值”,那么您可以观察到两个字典具有相同的键,因此同样的计数和做:

      var mergedDict = [String : String].init(minimumCapacity: hiraganaDictionary1.count)
      
      var bool = Bool.random()
      
      let keys = hiraganaDictionary1.keys.shuffled()
      
      for key in keys {
          mergedDict[key] = bool ? hiraganaDictionary1[key] : katakanaDictionary1[key]
          bool.toggle()
      }
      

      请注意,键在使用前已经过洗牌。否则,在迭代它们时,键的出现顺序与它们在字典的键值对中出现的顺序相同,这可能是有偏差的。这意味着,它可以预先确定任一字典中的哪些键将出现在结果字典中。

      改组键的更有效方法是改组索引:

      var mergedDict = [String : String].init(minimumCapacity: hiraganaDictionary1.count)
      
      var bool = Bool.random()
      
      let indices = hiraganaDictionary1.keys.indices.shuffled()
      
      for index in indices {
          let key = hiraganaDictionary1.keys[index]
          mergedDict[key] = bool ? hiraganaDictionary1[key] : katakanaDictionary1[key]
          bool.toggle()
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-22
        • 2017-03-24
        • 1970-01-01
        • 2016-02-08
        • 2017-11-13
        相关资源
        最近更新 更多