2015-10-02 59 views
0

我有大量的数据采用以下形式:[四个整数数组],{与整数数组有关的字符串集}。例如,集合 - 从字典中的字符串数组中提取

[1,1,1,8],{"(1+1+1)*8"} 

[1,1,2,8],{"1*(1 + 2)*8","(1 + 2)/(1/8)"} 

我有成千上万这些对保存在外部的文本文件,并需要能够回忆起的关键的四个整数的基础上,各条线。一种解决方案似乎是阅读文本文件导入在启动时一本字典,而是因为字典

let myDict2:Dictionary<Array<Int>, Array <String>> = [[1,1,1,8]: ["(1+1+1)*8"],[1,1,2,8]: ["1*(1 + 2)*8","(1 + 2)/(1/8)"]] 

明显的配方失败“类型‘数组’不符合协议‘哈希的’。”

但是,我们可以从一个整数数组转换键转换成字符串,以及与此尝试:

let myDict2:Dictionary<String, Array <String>> = ["1118": ["(1+1+1)*8"],"1128": ["1*(1 + 2)*8","(1 + 2)/(1/8)"]] 

没有错误,它甚至看起来我们可以提取与

let matches2=myDict2["1128"] // correctly returns ["1*(1 + 2)*8", "(1 + 2)/(1/8)"] 
结果

但是,当我们试图从答案拉元素具有与matches2[0],我们得到"Cannot subscript a value of type '[String]?'"

在我的键盘敲打随机,我得到了这窝k与matches2![0]但我不知道为什么。

  1. 有没有办法让我的原始字典尝试[整数,字符串集]工作?
  2. 在第二个公式[字符串,字符串集合]中,为什么matches2![0]工作和matches2[0]不是?
  3. 字典是一个合理的方法吗?还是有其他一些数据结构可以更好地实现我的目标?

回答

1

我先回答你的第二个问题:

let matches2=myDict2["1128"] // returns an Optional<Array<String>> 

dict[key]调用将返回一个可选的值,因为字典可能不包含该键。所以,你必须解开它首先

matches2[0] // error 
matches2![0] // ok 

现在到你的其他问题:一Dictionary适合的情况下,当你必须根据一键保持数据的唯一性。例如,如果每个人都需要一个唯一的社会安全号码,则应将SSN用作字典密钥,将人员信息用作其值。我不知道你的要求是什么,所以我会把它留在通用的。

将这四个数字连接成一个字符串是一个坏主意,除非所有数字都具有相同的数字位数。例如,(1,23,4,5)(12,3,4,5)将产生相同的字符串。

Array<Int>没有实现Hashable协议,所以你必须提供你自己的包装。这是我的尝试:

struct RowID : Hashable { 
    var int1: Int 
    var int2: Int 
    var int3: Int 
    var int4: Int 

    init(_ int1: Int, _ int2: Int, _ int3: Int, _ int4: Int) { 
     self.int1 = int1 
     self.int2 = int2 
     self.int3 = int3 
     self.int4 = int4 
    } 

    var hashValue : Int { 
     get { 
      return "\(int1),\(int2),\(int3),\(int4)".hashValue 
     } 
    } 
} 

// Hashable also requires you to implement Equatable 
func ==(lhs: RowID, rhs: RowID) -> Bool { 
    return lhs.int1 == rhs.int1 
      && lhs.int2 == rhs.int2 
      && lhs.int3 == rhs.int3 
      && lhs.int4 == rhs.int4 
} 

let myDict: [RowID: [String]] = [ 
    RowID(1,1,1,8): ["(1+1+1)*8"], 
    RowID(1,1,2,8): ["1*(1 + 2)*8","(1 + 2)/(1/8)"] 
] 

let id = RowID(1,1,2,8) 
let value = myDict[id]![0] 

// You can also access it directly 
let value2 = myDict[RowID(1,1,1,8]]![0] 
+0

由于整数数组的限制,我知道如果转换为字符串形式没有不明确的条目。但是,您的Hashable和Equatable的示例实现在将来肯定会派上用场。谢谢。 –