在Swift中将字符串减少为字典

时间:2015-09-30 23:44:20

标签: arrays swift dictionary swift2

将一个像AAA:111;BBB:222;333;444;CCC:555这样的字符串缩减为Swift字典的简单方法是什么。我有以下代码:

var str = "AAA:111;BBB:222;333;444;CCC:555"
var astr = str.componentsSeparatedByString(";").map { (element) -> [String:String] in
    var elements = element.componentsSeparatedByString(":")
    if elements.count < 2 {
        elements.insert("N/A", atIndex: 0)
    }
    return [elements[0]:elements[1]]
}


上面的代码生成 Dictionaries 数组
[["A": "111"], ["BBB": "222"], ["UKW": "333"], ["UKW": "444"], ["CCC": "555"]]

我希望它能够生产 ["A": "111", "BBB": "222", "UKW": "333", "UKW": "444", "CCC": "555"]

但是我没有尝试,因为我在数组上调用map函数,似乎无法转换map函数的结果的性质。

注意:字符串格式的字典被描述为具有KEY:VALUE;格式或VALUE;格式,在这种情况下,映射函数会将"N/A"添加为未命名的密钥值。

非常感谢任何有关此事的帮助。

4 个答案:

答案 0 :(得分:7)

您的arrayUDID=[] arrayUser=[] arrayHash=[] array1=[] f = File.open("Original.csv", "r") f.each_line { |line| row = line.split(","); arrayUDID<<row[9] arrayUser<<row[9] } arrayUser = arrayUser.uniq arrayHash = [] for i in 0..arrayUser.size-1 arrayHash<<arrayUser[i] arrayHash<<i end hash = Hash[arrayHash.each_slice(2).to_a] array1=hash.values_at *arrayUDID logfile = File.new("Processed.csv","w") for i in 0..array1.size-1 logfile.print("#{array1[i]}\n") end logfile.close 会生成一系列词典。当你想将它们组合成1时,这对map来说是一个完美的工作:

reduce

Swift没有默认运算符来“合并”两个func + <K,V>(lhs: Dictionary<K,V>, rhs: Dictionary<K,V>) -> Dictionary<K,V> { var result = Dictionary<K,V>() for (key, value) in lhs { result[key] = value } for (key, value) in rhs { result[key] = value } return result } var str = "AAA:111;BBB:222;333;444;CCC:555" var astr = str .componentsSeparatedByString(";") .reduce([String: String]()) { aggregate, element in var elements = element.componentsSeparatedByString(":") if elements.count < 2 { elements.insert("N/A", atIndex: 0) } return aggregate + [elements[0]:elements[1]] } print(astr) ,所以你必须定义一个。请注意,Dictionaries此处不可交换:+。如果两个词典中都存在键,则将使用第二个词典中的值。

答案 1 :(得分:4)

这是reduce的作品:

let str = "AAA:111;BBB:222;333;444;CCC:555"
let keyValueStrings = str.componentsSeparatedByString(";")
let dictionary = keyValueStrings.reduce([String: String]()) {
    aggregate, element in

    var newAggregate = aggregate

    let elements = element.componentsSeparatedByString(":")
    let key = elements[0]

    // replace nil with the value you want to use if there is no value        
    let value = (elements.count > 1) ? elements[1] : nil
    newAggregate[key] = value

    return newAggregate
}

print(dictionary)

您也可以直接aggregate变更:

let dictionary = keyValueStrings.reduce([String: String]()) {
    (var aggregate: [String: String], element: String) -> [String: String] in

    let elements = element.componentsSeparatedByString(":")
    let key = elements[0]

    // replace nil with the value you want to use if there is no value        
    let value = (elements.count > 1) ? elements[1] : nil
    aggregate[key] = value

    return aggregate
}

这是一种功能性方法,但您可以使用for迭代实现相同的功能。

答案 2 :(得分:1)

发生这种情况的原因是因为map只能返回数组。如果您使用此方法来解析字符串,则需要在之后将其转换为字典。

var newDict = [String:String]()
for x in astr {
    for (i, j) in x {
        newDict[i] = j
    }
}

答案 3 :(得分:0)

您的代码的当前问题是map函数迭代包含[["key:value"],["key:value"]..]的数组并再次将其分开。但它会返回["key":"value"],然后您将其添加到数组中。

相反,您可以将elements[0]:elements[1]直接添加到本地保存的变量中,这将解决您的问题。像

这样的东西

finalVariable[elements[0]] = elements[1]