"For-in loop requires '[String]?' to conform to 'Sequence'; did you mean to unwrap optional?" 但我不认为我在使用可选项

"For-in loop requires '[String]?' to conform to 'Sequence'; did you mean to unwrap optional?" but I don't think I am using optionals

这是我正在尝试做的但简化了的事情:

var adictionary = [String:[String]]()
adictionary["A"] = ["B", "C"]
adictionary["B"] = ["A", "C"]
adictionary["C"] = ["A"]
adictionary["D"] = []

var newdic = Array(adictionary.keys).reduce(into: [String: Bool]()) { [=11=][] = false } //I make an arr from a dictionary's keys of type [String:[String]]

for (key, val) in newdic{
     for arr in adictionary[key]{
          if !(adictionary[arr].contains(key)){
               newdic[key] = true
          }
     }
}

当我 运行 我试图 运行 在 ios 应用程序中 运行 代码的上述简化版本时,我得到了这些错误:

main.swift:12:28: 错误:可选类型“[String]?”的值?必须解包为“[String]”类型的值 for arr in adictionary[key]{

main.swift:12:28: 注意:合并使用 '??'当可选值包含 'nil' 时提供默认值 for arr in adictionary[key]{

main.swift:12:28: 注意:使用 '!' 强制解包如果可选值包含 'nil' 则中止执行 for arr in adictionary[key]{

我不明白,我这样做有什么问题吗?这些错误是什么意思?好像 Swift 认为我在某个地方有一个可选的?但我不知道我该怎么做...非常感谢任何帮助。

如果我更改此行:for arr in adictionary[key]{

收件人:for arr in adictionary[key]!{

它修复了 if !(a... 行中出现的问题和新错误。我仍然不明白为什么修复它。

Swift 字典总是访问 return 可选的 值,因为如果键不存在,查找将 return nil不存在。由您来处理由此产生的 optional 是一种安全的方式。添加 ! 很少是修复它的正确方法,因为如果 nil 被 return 编辑,您的代码将崩溃。

您第一次获得 可选 是在这里:

for arr in adictionary[key] {

同样,Swift 不知道 key 是否存在于 adictionary 中,因此它 return 是一个 可选的 。解决此问题的一种安全方法是使用字典查找,当键不存在时,该字典查找 return 是一个 default 值。在这种情况下,returning 一个空数组似乎是一个不错的选择,因为你的 for 循环将什么都不做:

for arr in adictionary[key, default:[]] {

接下来,你在这里得到一个可选

if !(adictionary[arr].contains(key)){

同样,您需要决定如何安全地处理 dictionary[arr] 可以 return nil 的事实。同样的技巧在这里起作用:return 如果 arr 不存在则为空数组:

if !(adictionary[arr, default:[]].contains(key)){

这是您的代码的最终版本:

var adictionary = [String:[String]]()
adictionary["A"] = ["B", "C"]
adictionary["B"] = ["A", "C"]
adictionary["C"] = ["A"]
adictionary["D"] = []

var newdic = Array(adictionary.keys).reduce(into: [String: Bool]()) { [=14=][] = false } //I make an arr from a dictionary's keys of type [String:[String]]
print(newdic)

for key in newdic.keys {
    for arr in adictionary[key, default:[]] {
        if !(adictionary[arr, default:[]].contains(key)){
               newdic[key] = true
          }
     }
}

这里有一个类似的方法,没有你提到的问题。

var adictionary = [String:[String]]()
adictionary["A"] = ["B", "C"]
adictionary["B"] = ["A", "C"]
adictionary["C"] = ["A"]
adictionary["D"] = []

var newdic = Array(adictionary.keys).reduce(into: [String: Bool]()) { [=10=][] = false }

let notEmptValues = adictionary.values.filter { [=10=].count > 0 }.reduce([], +)
let duplicates = Array(Set(notEmptValues.filter { i in notEmptValues.filter { [=10=] == i }.count > 1 })).sorted(by: { [=10=] <  })
if let result = adictionary.first(where: { [=10=].value.sorted(by: { [=10=] <  }) == duplicates })?.key {
    newdic[result] = true
}

print(newdic)