如何使用与 String Swift 同名的变量

How to use variable with the same name as String Swift

我正在尝试优化我的代码。我想执行以下操作:如果我在 firstNames 数组中的字典 dict 中有一个元素,我想将此元素直接写入 first 变量,与 [=15 相同=] 等。这是我的代码示例。我创建了 names 数组,其中包含链接变量 firstNames <-> firstsecondNames <-> second 等。 此外,我正在尝试遍历循环并将值设置为 firstsecond 等。使用 val

    let dict = ["type": "1", "word": "abc"] // this is example
    let firstNames = ["1", "2"]
    let secondNames = ["3", "4"]
    var first = String()
    var second = String()
    let names = [firstNames: first, secondNames: second]
    for el in dict {
        for var (key, val) in names {
            if (key as! [String]).contains(el["type"]!) {
                if ((val as! String) != "") {
                    val = (val as! String) + ", " + el["word"]!
                }
                else {
                    val = el["word"]!
                }
            }
        }
    }

此代码没有任何运行时错误。但不幸的是,当我试图在循环中设置 val 时,什么也没有发生。我做错了什么或者可能有更优雅的解决方案?

感谢您的帮助。

我的猜测是 'val' 是临时变量,无法分配给它,因此它会影响 'dict' 字典。

而不是

val = ..

尝试使用

dict[key] = ... 

此外,如果您能描述一下您试图通过代码实现的目标,那就太好了。

Swift 是一种编译的、主要是静态的语言,如果不需要,优化器可以自由地完全删除这些临时变量。局部变量的名称在运行时不可用。这种方法行不通。如果您使用字典将 "first" 和 "second" 保存为字符串键(这是 Paulw11 指向您的位置),它可能会起作用,但这是 Swift.[=16 中的错误方法=]

让我们从字典开始。这不是字典的正确使用。这不是字符串到字符串的任意映射。它是 specific 字段标识符到值的映射。那是结构体的定义。

有可能 "type" 确实是 "an arbitrary integer," 但我强烈怀疑它实际上是 "a value from a constrained list of values." 那是一个枚举。

如果我们把它们放在一起,dict 就是真正的元素:

enum ElementType {
    case one
    case two
    case three
    case four
}

struct Element {
    let type: ElementType
    let word: String
}

并且您的名称选择器是 ElementTypes 的任意列表:

let firstNameTypes = [ElementType.one, .two]
let secondNameTypes = [ElementType.three, .four]

然后,我们可以想象元素列表(我假设您实际上已经在这个循环之外),而不是只有一个字典。

let elements = [
    Element(type: .one, word: "abc"),
    Element(type: .two, word: "bcd"),
    Element(type: .three, word: "efg"),
    Element(type: .four, word: "fgh"),
]

现在我们的循环很简单并且清楚地说明了它的含义。

let firstNames = elements.filter { firstNameTypes.contains([=13=].type) }
let secondNames = elements.filter { secondNameTypes.contains([=13=].type) }

要获得我们的最终字符串也很简单:

let firstString = firstNames.map { [=14=].word }.joined(separator: ",")
let secondString = secondNames.map { [=14=].word }.joined(separator: ",")

虽然这段代码非常清晰,但它确实对元素进行了两次迭代,并针对每个元素对 "NameTypes" 列表进行了一次迭代。在绝大多数情况下,这很好。这是计算机所做的,但是如果你有成千上万的元素(特别是如果名称过滤列表很长),它可能会很昂贵,我们可以编写一个返回结果字符串字典的函数(通过重写 filter用手)。如果那是你的问题,我可以把它写下来(如果你能更清楚地解释潜在的问题),但在大多数情况下,对于中等大小的列表,这是最好的方法。