'((键:字符串,值:任意))不能转换为'[字符串:任意]

时间:2019-01-17 13:03:39

标签: swift

我正在尝试重构此代码:

var indices = [String:[Int:Double]]()
apps.forEach { app in indices[app] = [Int:Double]()}

var index = 0
timeSeries.forEach { entry in
    entry.apps.forEach{ (arg: (key: String, value: Double)) in
        let (app, value) = arg
        indices[app]?[index] = value
    }

    index += 1
}

所以我有签名:

var parameters = timeSeries.map{ entry in entry.apps as [String:Any] }
var indices = getIndices(with: apps, in: parameters) as? [String:[Int:Double]] ?? [String:[Int:Double]]()

和方法:

func getIndices(with source: [String], in entryParameters: [[String:Any]]) -> [String:[Int:Any]] {
    var indices = [String:[Int:Any]]()
    source.forEach { item in indices[item] = [Int:Any]() }

    var index = 0
    entryParameters.forEach { (arg: (key: String, value: Any)) in
        let (key, value) = arg
        indices[key]?[index] = value

        index += 1
    }

    return indices
}

但这(仅在方法中有效,而不是原始方法,效果很好)给出:'(key: String, value: Any)' is not convertible to '[String : Any]' entryParameters

我必须使用Any的原因是因为另一个来源是[String:[Int:Bool]]

编辑:更多详细信息:

timeSeries是[TimeSeriesEntry]

// this will need to be defined per-model, so in a different file in final project
struct TimeSeriesEntry: Codable, Equatable {
    let id: String
    let uid: String
    let date: Date
    let apps: [String:Double]
    let locations: [String:Bool]

    func changeApp(app: String, value: Double) -> TimeSeriesEntry {
        var apps = self.apps
        apps[app] = value

        return TimeSeriesEntry(id: self.id, uid: self.uid, date: self.date, apps: apps, locations: self.locations)
    }
}

注释:

更改了呼叫签名,谢谢。问题仍然存在。

2 个答案:

答案 0 :(得分:1)

问题在于entryParameters中的每个值都是一个字典,因此当您执行entryParameters.forEach时,您会在闭包中得到字典类型,而不是(key, value)

在此词典上调用(key,value)时,您将得到forEach。因此,您的方法应如下所示:

func getIndices(with source: [String], in entryParameters: [[String:Any]]) -> [String:[Int:Any]] {
    var indices = [String:[Int:Any]]()
    source.forEach { item in indices[item] = [Int:Any]() }

    var index = 0
    entryParameters.forEach { entry in
        entry.forEach {(arg: (key: String, value: Any)) in
            let (key, value) = arg
            indices[key]?[index] = value
        }

        index += 1
    }

    return indices
}

答案 1 :(得分:0)

我刚刚在Playground中对此进行了简短的测试。

var double = [String:[Int:Double]]()
double["Taco"] = [2: 3.2]

func myFunc(double: [String:[Int:Double]]) {
    print(double.count) //Prints 1
    print(double["Taco"]!) //Prints [2:3.2]
}

func myFunc2(all: [String:Any]) {
    print(all.count) //Prints 1
    print(all["Taco"]!) //Prints [2:3.2]
}


myFunc(double: double)
myFunc2(all: double as [String:Any])

我有我的首字母[String:[Int:Double]]()。在此字典中,我设置了double["Taco"] = [2: 3.2]。我可以使用2种不同的函数,其中一种被当作原始类型[String:[Int:Double]]使用,由于这些函数采用相同的参数类型,因此易于使用。但是,现在我创建了一个函数,该函数接受[String:Any]的字典。现在,要使用此方法,在调用该方法时,我们必须将变量强制转换为[String:Any],如下所示。