Ios &引用;For in-loop需要';[字符串]?';符合';顺序';;你的意思是打开可选的;但我不知道';I don’我不认为我在用可选的

Ios &引用;For in-loop需要';[字符串]?';符合';顺序';;你的意思是打开可选的;但我不知道';I don’我不认为我在用可选的,ios,swift,for-in-loop,Ios,Swift,For In Loop,以下是我试图做的事情,但简化了: var adictionary = [String:[String]]() adictionary["A"] = ["B", "C"] adictionary["B"] = ["A", "C"] adictionary["C"] = ["A"] adictionary["D"] = [

以下是我试图做的事情,但简化了:

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]()) { $0[$1] = 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]”类型的值 对于字典中的arr[键]{

main.swift:12:28:注意:当可选值包含“nil”时,使用“?”合并以提供默认值 对于字典中的arr[键]{

main.swift:12:28:注意:如果可选值包含“nil”,则使用“!”强制展开以中止执行 对于字典中的arr[键]{

我不明白,我所做的有什么不对?这些错误是什么意思?斯威夫特似乎认为我有一个可选的地方?但我不知道我怎么做…任何帮助都是非常感谢的

如果我更改此行:对于字典[key]中的arr{

收件人:对于字典[key]中的arr{


它修复了问题,并在if上出现了新的错误!(a…行。我仍然不明白为什么会修复它。

Swift字典访问总是返回可选值,因为如果键不存在,查找将返回
nil
。由您来处理结果可选是一种安全的方法。添加
很少是修复它的正确方法,因为如果<返回code>nil

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

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

for arr in adictionary[key, default:[]] {
接下来,您将在此处获得一个可选选项:

同样,您需要决定如何安全地处理
dictionary[arr]
可能返回
nil
的事实。同样的技巧也适用于此:如果
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]()) { $0[$1] = 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]()) { $0[$1] = false }

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

print(newdic)
var-adictionary=[String:[String]]()
词典[“A”]=[“B”,“C”]
字典[“B”]=[“A”,“C”]
字典[“C”]=“A”]
D字典[“D”]=[]
var newdic=Array(adictionary.keys).reduce(到:[String:Bool]()){$0[$1]=false}
让notEmptValues=adictionary.values.filter{$0.count>0}.reduce([],+)
让duplicates=Array(Set(notEmptValues.filter{i in notEmptValues.filter{$0==i}.count>1}))。排序(按:{$0<$1})
如果let result=adictionary.first(其中:{$0.value.sorted(by:{$0<$1})==duplicates})?.key{
newdic[结果]=真
}
打印(新DIC)

adictionary[key]
始终是可选的。字典就是这样工作的。正如马特所说,你“知道有一个与
key
相关的值,因为你首先从字典的键中得到
键,但斯威夫特“不知道”“那就是。访问字典总是返回一个可选值,因为可能有,也可能没有,与给定键关联的值。强制展开可以解决问题,但与
?[]合并则为零。”
是一种更安全的方法。你没有说你的代码实际上想要实现什么,但是
集合
可能是一种更好的数据结构。Ben如果你不这样做,就没有必要预加载
;你的字典可以包含
/
对不起,我不理解这部分:在这种情况下,返回空数组似乎是一个不错的选择,因为for循环“为什么我要返回[]”然后退出我的函数?如果该键真的不作为另一个字典的键存在,我想我宁愿它跳过它并继续,这样continue语句会更有意义。我将查找swift中默认值的作用,然后返回到这个。还要查找nil coalescing是什么,我也不理解
default:
提供当键不存在时字典查找返回的值。对于我的代码,将返回一个空数组,该数组完全符合您的要求。由于数组中没有元素,因此将跳过内部for循环,代码将继续到下一个键。“if!(adictionary[arr,默认值:[]).contains(key)){“这基本上就像使用一个nil合并操作符?有点像说”?[]”,我理解对了吗?谢谢你教我是的,它非常像nil合并操作符
if!((adictionary[arr]?[])。contains(key))){
,但它还有一个附加的好处,那就是你可以附加到它上面。如果你创建了一个新的字典来计算一个单词中的字母,你可以说
dict[letter,default:0]+=1
,当你第一次看到一个字母时,它会创建字典条目并递增它。
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]()) { $0[$1] = 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]()) { $0[$1] = false }

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

print(newdic)