将一个像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"
添加为未命名的密钥值。
非常感谢任何有关此事的帮助。
答案 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]