Swift 从CSV文件中分离字符串
目前,我允许用户导入从Swift 从CSV文件中分离字符串,swift,string,csv,dictionary,Swift,String,Csv,Dictionary,目前,我允许用户导入从Excel或Numbers创建的CSV文件。工作表有多个字段,我可以毫无问题地导入这些字段 但是,其中一个字段如下所示: "[Title1: (100: S11), (100: S12), (100: 10), (100: 2), (100: 3)], [Title2: (300: 50), (300: 90), (300: 100a), (300: D), (300: E)], [Title3: (500: 2), (500: 112), (500: 6), (500:
Excel
或Numbers
创建的CSV文件。工作表有多个字段,我可以毫无问题地导入这些字段
但是,其中一个字段如下所示:
"[Title1: (100: S11), (100: S12), (100: 10), (100: 2), (100: 3)], [Title2: (300: 50), (300: 90), (300: 100a), (300: D), (300: E)], [Title3: (500: 2), (500: 112), (500: 6), (500: 110), (500: 113)]"
//[String: [[Int: String]]]
[
"Title1": [[100: "S11"], [100: "S12"], [100: "10"], [100: "2"], [100: "3"]],
"Title2": [[300: "50"], [300: "90"], [300: "100a"], [300: "D"], [300: "E"]],
"Title3": [[500: "2"], [500: "112"], [500: "6"], [500: "110"], [500: "113"]]
]
我应该如何将此字段拆分为如下所示的词典:
"[Title1: (100: S11), (100: S12), (100: 10), (100: 2), (100: 3)], [Title2: (300: 50), (300: 90), (300: 100a), (300: D), (300: E)], [Title3: (500: 2), (500: 112), (500: 6), (500: 110), (500: 113)]"
//[String: [[Int: String]]]
[
"Title1": [[100: "S11"], [100: "S12"], [100: "10"], [100: "2"], [100: "3"]],
"Title2": [[300: "50"], [300: "90"], [300: "100a"], [300: "D"], [300: "E"]],
"Title3": [[500: "2"], [500: "112"], [500: "6"], [500: "110"], [500: "113"]]
]
这个字段是由用户自己创建的,看起来已经有点太复杂了,而且容易出错。也许一个更好的问题是如何更好地格式化此字段,而不是将此字段拆分到我想要的字典中
可能是一个简化版本:
//[String: [Int: [String]]]
[
"Title1": [100: ["S11", "S12", "10", "2", "3"]],
"Title2": [300: ["50", "90", "100a", "D", "E"]],
"Title3": [500: ["2", "112", "6", "110", "113"]]
]
关于此字段的一些说明:
标题:可以是任何内容,它是嵌套字典的标题
嵌套字典中的键可以是100、200、300、400、500或600
嵌套字典中的值是一个字符串
,它与嵌套字典中的键一起形成一个唯一键
这意味着:
100: "S11" and 200: "S11" // valid
100: "S11" and 100: "S11" // not valid
这段代码产生了我想要的结果,但它看起来非常丑陋,而且它太依赖于值的位置(而不是检查值)
关于如何使用更简单、更优雅的方法执行此操作,您有什么建议吗?下面的代码应该根据需要将您提供的数据解析到字典中:
let data = "[Title1: (100: S11), (100: S12), (100: 10), (100: 2), (100: 3)], [Title2: (300: 50), (300: 90), (300: 100a), (300: D), (300: E)], [Title3: (500: 2), (500: 112), (500: 6), (500: 110), (500: 113)]"
let arr1 = data.components(separatedBy:"],")
var dic = [String:[[String:Any]]]()
for row1 in arr1 {
let arr2 = row1.components(separatedBy:",")
var key = ""
for row2 in arr2 {
var txt = row2.replacingOccurrences(of:" ", with:"")
if txt.hasPrefix("[Title") {
// First row
txt = txt.replacingOccurrences(of:"[", with:"")
let arr3 = txt.components(separatedBy:":")
key = arr3[0]
let key1 = arr3[1].replacingOccurrences(of:"(", with:"")
let val1 = arr3[2].replacingOccurrences(of:")", with:"").replacingOccurrences(of:" ", with:"")
dic[key] = [[key1:val1]]
} else {
let arr3 = row2.components(separatedBy:":")
let key1 = arr3[0].replacingOccurrences(of:"(", with:"").replacingOccurrences(of:" ", with:"")
let val1 = arr3[1].replacingOccurrences(of:")", with:"").replacingOccurrences(of:"]", with:"").replacingOccurrences(of:" ", with:"")
dic[key]?.append([key1:val1])
}
}
}
print(dic)
上面回答了您的第一个问题,即如何按照指定将提供的数据解析到词典中。第二个问题有点复杂,因为我对数据了解不够,无法提供有用的答案。但现在可能没有必要了,因为可以根据需要将数据拆分到字典中?:) 我假设您选择了第一种导出格式,即
[Title1: (100: S11), (100: S12), (100: 10), (100: 2), (100: 3)], [Title2: (300: 50), (300: 90), (300: 100a), (300: D), (300: E)], [Title3: (500: 2), (500: 112), (500: 6), (500: 110), (500: 113)]
您可以使用正则表达式来解析该字符串。下面的答案不处理错误。如果您的标题包含分号(:
),它也将不起作用
扩展字符串{
下标(u范围:NSRange)->字符串{
让startIndex=self.utf16.index(self.utf16.startIndex,offsetBy:range.location)
让endIndex=self.utf16.index(startIndex,offsetBy:range.length)
返回字符串(描述:self.utf16[startIndex..您应该定义一个结构来保存此数据。使用数组和dict会很快变得混乱。(100:S11)、(100:S12)
代表什么?我将创建一个结构(或者更确切地说是NSManagedObject
,因为我必须将其保存在CoreData中)。(100:S12)
表示(Int:String)
其中100
表示类别,而S12
表示标识符。我认为您需要认真重新考虑Excel模板。导出为纯文本已经够糟糕的了。将其嵌套更糟糕。如果类别名称中有空格,例如“今日特价”,您的解决方案将无法工作@CodeDifferent:这正是我担心的。我让用户使用Excel导入的唯一原因是,我需要至少一种方法让他们将菜单导入应用程序。其他字段只包含1个“字符串”,所以应该可以(尽管我需要检查它们是否真的“唯一”).但是,此问题中的字段是创建“完整菜单”有选项可供选择。在正常情况下,他们不需要指定,但可以指定。此外,我真的希望它保存在1CSV
文件中,以便我也可以使用相同的格式进行导出。尽管如此,考虑到这些限制,还有什么建议我可以使用吗?另外,我正在考虑使用NSRegularExpression
为了得到结果,我可以把标题放在括号里,把项目放在括号里。谢谢你的建议。这确实得到了我想要的结果。但我觉得我的数据源很容易出错。也许我应该试着找到一种更好的方法来创建源。这是只有你才知道的最好的方法关于事情,因为我们没有所有的信息。如果我的回答有帮助,请标记为“正确”。如果您正在寻找一种不同的方法,而这个问题与此无关,那么您可能想删除它?如果您不介意,我会将此问题保留一段时间。我提供了有关来源的更多信息,因此可能会对问题有更大的帮助。如果没有,我会将此标记为已回答。这是您的问题,f您可以自由地做任何适合您的事情:)但从我的角度来看,试图回答如何设置数据源的问题,我需要知道数据源是什么,以及它如何将数据提供给应用程序?它是您控制的API端点吗?如果是,是否可以以JSON格式提供数据?如果源不在您的控制范围内,那么您实际上在做什么当你说你必须找到一种更好的方法来创建源代码时,你在想什么?好吧,源代码来自Excel(或数字)。用户应该能够在Excel中输入信息并将其导出到CSV
,这样就可以将其导入到应用程序中。因此,简而言之,用户可以决定他想要使用的任何格式(目前),但我想让它对用户来说尽可能简单,如果你问我,它已经太复杂了:p。