是否可以将带有可变数组的字典作为Swift中的值

时间:2014-07-20 21:48:01

标签: dictionary swift

我正在尝试这样做:

var dictArray = [String:[String]]()
dictArray["test"] = [String]()
dictArray["test"]! += "hello"

但我收到了奇怪的错误NSString is not a subtype of 'DictionaryIndex<String, [(String)]>'

我只是希望能够将对象添加到字典中的数组中。

更新:看起来Apple认为这是一个已知问题&#34;在Swift中,暗示它将按预期工作最终。来自Xcode 6 Beta 4发行说明:

  

...同样,您无法修改mutable的基础值   可选值,有条件地或在强制解包内:

tableView.sortDescriptors! += NSSortDescriptor(key: "creditName", ascending: true)
     

解决方法:显式测试可选值,然后分配   结果回来了:

if let window = NSApplication.sharedApplication.mainWindow {
    window.title = "Currently experiencing problems"
}
tableView.sortDescriptors = tableView.sortDescriptors!

5 个答案:

答案 0 :(得分:10)

你只能这样做

var dictArray = [String:[String]]()
dictArray["test"] = [String]()
var arr = dictArray["test"]!;
arr += "hello"
dictArray["test"] = arr

因为dictArray["test"]会给你Optional<[String]>这是不可变的

  6> var test : [String]? = [String]()
test: [String]? = 0 values
  7> test += "hello"
<REPL>:7:1: error: '[String]?' is not identical to 'UInt8'

由于同样的原因,

append也无效,Optional是不可变的

  3> dictArray["test"]!.append("hello")
<REPL>:3:18: error: '(String, [(String)])' does not have a member named 'append'
dictArray["test"]!.append("hello")
                 ^ ~~~~~~

顺便说一下,错误信息太可怕......

答案 1 :(得分:1)

您可以使用NSMutableArray而不是[String]作为字典的值类型:

var dictArray: [String: NSMutableArray] = [:]
dictArray["test"] = NSMutableArray()
dictArray["test"]!.addObject("hello")

答案 2 :(得分:0)

这仍然是Swift 3中的一个问题。至少我能够创建可以为你处理它的方法。

func appendOrCreate(newValue: Any, toArrayAt key: String, in existingDictionary: inout [AnyHashable:Any]) {

    var mutableArray = [Any]()

    if let array = existingDictionary[key] as? [Any]{
        //include existing values in mutableArray before adding new value
        for existingValue in array {
            mutableArray.append(existingValue)
        }
    }

    //append new value
    mutableArray.append(newValue)

    //save updated array in original dictionary
    existingDictionary[key] = mutableArray
}

答案 3 :(得分:0)

问题在于我们需要类语义,但必须使用结构。如果你将类对象放入字典中,你就得到了你想要的东西!

因此,如果¹具有可变值,则可以将它们包装在类中并使用闭包执行更新:

$(document).ready(function(e) {
    $(".mobile-button").click(function(event) {
        $("#content").addClass("mobile-open");
        event.stopPropagation();
    });

    $(document).click(function(event){
        if (!$(event.target).hasClass('link')) {
            $("#content").removeClass("mobile-open");
        }
    });
});

示例:

class MutableWrapper<T> {
    var rawValue: T

    init(_ val: T) {
        self.rawValue = val
    }

    func update(_ with: (inout T) -> Void) {
        with(&self.rawValue)
    }
}

对于它的价值,我没有看到让调用者和包装器保持同步的方法。即使我们声明func foo() { var dict = [String: MutableWrapper<[String]>]() dict["bar"] = MutableWrapper(["rum"]) dict["bar"]?.update({$0.append("gin")}) print(dict["bar"]!.rawValue) // > ["rum", "gin"] } ,我们也会在init(_ val: inout T)中找到副本。

  1. 性能不一定是个问题,因为编译器会大量优化结构。我会根据代码中的大量复制更新对任何可变解决方案进行基准测试。

答案 4 :(得分:0)

从 Swift 4.1 开始,您可以 provide a default value to the subscript 这让您现在可以很自然地解决这个问题:

dictArray["test", default: []].append("hello")