单值多键字典-Swift
我正在尝试创建一个应用程序,根据预先确定的映射,将英文字母映射到各种RNA密码子(A、C、U或G的序列,3个一组) 要将英语转换为RNA,字典如下所示:单值多键字典-Swift,swift,dictionary,Swift,Dictionary,我正在尝试创建一个应用程序,根据预先确定的映射,将英文字母映射到各种RNA密码子(A、C、U或G的序列,3个一组) 要将英语转换为RNA,字典如下所示: var englishTomRNA: [Character: [String]] = ["A": ["UUU", "UAC"], "Q": ["UUA"], "S": [
var englishTomRNA: [Character: [String]] = ["A": ["UUU", "UAC"],
"Q": ["UUA"],
"S": ["UCU", "UCC", "UCA"]]
等等
正如您所见,任何给定的英语字符(代表一个多基因基因型的生物学特征)都有多个值,我对转换这些值没有问题
然而,我在实现上确实有一个问题,那就是字典以另一种方式隐藏。我最初使用的switch:case
语句如下:
for codon in preEnglishInputString {
switch codon {
case "UUU", "UAC": inEnglish.append("A")
case "UUA": inEnglish.append("Q")
case "UCU", "UCC", "UCA", "UCG": inEnglish.append("S")
}
}
但是,现在我希望将RNA->English转换函数转换为使用字典,以便更符合此实现
我不知道如何为一个值设置多个键(与上面使用的为一个键设置多个值相反)
尝试以下操作时,不起作用:
let mRNAtoEnglish: [[String] : Character] =
[["UUU", "UAC"] : "A",
["UUA", "UUG"] : "Q",
["UCU", "UCC", "UCA"] : "S"]
当编译器大喊时,类型[String]不符合协议“Hashable”
我只是使用了错误的数据结构,还是有一些语法我不知道?(我对斯威夫特还不太熟悉)
谢谢 不能将数组用于字典键。钥匙是独一无二的。同一个键在字典中不能出现两次,但不同的键可能指向同一个值。所有键必须为同一类型,所有值必须为同一类型 因此,正如Leo所评论的,使用相同的值保存3个键,而不是使用3个键保存单个数组:
let mRNAtoEnglish: [String : Character] =
["UUU": "A",
"UAC": "A",
"UUA": "Q",
"UUG": "Q",
"UCU": "S",
"UCC": "S",
"UCA": "S"]
使用Swift的高阶功能:
var englishTomRNA: [Character: [String]] = ["A": ["UUU", "UAC"],
"Q": ["UUA"],
"S": ["UCU", "UCC", "UCA"]]
var inEnglish = ""
// Sample Input
let preEnglishInputString = ["UUA", "UCC", "UUU"]
for codon in preEnglishInputString {
let english = englishTomRNA
.filter { $0.1.contains(codon) }
.first!.0
inEnglish.append(english)
}
print(inEnglish) // QSA
这需要两个假设:
preEnglishInputString
中的每个密码子代码都是有效的,可以在您的englishTomRNA
字典中找到它的作用是:
.filter{…}
查找包含密码子的任何键值对。在字典上调用filter
时,它会退化为(键、值)
的元组,因此$0.1
指的是值filter
始终返回匹配数组,即使它只找到一个匹配
首先代码>从列表中获取第一个匹配项(假设1)。感叹号假设始终找到匹配项(假设2)
.0
获取键值对的键,该键值对包含英文字符。如果您想要基于词典的答案,这将生成与englishTomRNA
相反的版本
var englishTomRNA: [Character: [String]] = ["A": ["UUU", "UAC"],
"Q": ["UUA"],
"S": ["UCU", "UCC", "UCA"]]
var mRNAtoEnglish = [String:Character]()
for (key, value) in englishTomRNA {
for mRNA in value {
mRNAtoEnglish[mRNA] = key
}
}
print(mRNAtoEnglish)
// ["UUU": "A", "UCA": "S", "UCC": "S", "UAC": "A", "UUA": "Q", "UCU": "S"]
只需使用相同的值保存3个键,而不是使用3个键保存单个数组keys@LeoDabus请参见luiyezheng的答案+我的评论以获取更新!查看我在James answer上的评论我很欣赏这个答案,但是@Code Different的答案允许我将字典转换为类变量并节省内存,并尝试使用更高阶的函数(来自Java背景,这些东西对我来说还是新的,还没有在我当前的CompSci类的版本8中使用它们). 谢谢你!键入另一本文字词典不仅可以节省内存,还可以增加出错的几率。让我们承认:输入技术数据是相当困难的。@code不同的是,整个字典总共包含64个密码子#ThankNuthForcOpyandPaste编写代码来解析第一个字典以生成第二个字典并不困难,这样就消除了更多键入错误的机会。如果您在长字符串密码子上调用此功能,重复过滤将花费大量时间。luiyezhang的基于词典的答案将表现得更好,并且在节省时间方面花费的内存量可以忽略不计。你的密码子数组必须非常长,大约一百万个密码子,执行时间才能有所不同。即使如此,我还是宁愿在代码中使用mRNAtoEnglish
而不是在新的文字词典中键入。我的答案是以编程方式创建词典。englishTomRNA.forEach({(key,value)in value.forEach({mRNAtoEnglish[$0]=key})