swift 3.1 how to get array or dictionary from CSV

前端 未结 4 1272
孤独总比滥情好
孤独总比滥情好 2020-12-24 01:50

How could I use data in this kind of CSV file? Or how could I print for example row 2 value for \"inside\" column and assign it to a property / entity?

I have this k

相关标签:
4条回答
  • 2020-12-24 02:27

    
This is for CSV file for swift 4.2 at 20181208

      var dataArray : [String] = []
          if  let path = Bundle.main.path(yourfile: "svenskaidiom", ofType: "csv")  
          {
            dataArray = []
            let url = URL(fileURLWithPath: path)
            do {
                let data = try Data(contentsOf: url) 
                let dataEncoded = String(data: data, encoding: .utf8)
                if  let dataArr = dataEncoded?.components(separatedBy: "\r\n").map({ $0.components(separatedBy: ";") })
              {
                for line in dataArr
                {
                        dataArray?.append(line)
                }
            }
            }
            catch let jsonErr {
                print("\n Error read CSV file: \n ", jsonErr)
            }
            }
    
    0 讨论(0)
  • 2020-12-24 02:35

    Swift 4

    Sometime CSV file is more complicated such as special characters (e.g. comma), the values are surrounded by double quotes as examples below:

    Hello, "Complicated String, with a comma inside", 123
    

    In this case, I use:

    let dataString: String! = String.init(data: data!, encoding: .utf8)
    var items: [(String, String, String)] = []
    let lines: [String] = dataString.components(separatedBy: NSCharacterSet.newlines) as [String]
    
    for line in lines {
        var values: [String] = []
        if line != "" {
            if line.range(of: "\"") != nil {
                var textToScan:String = line
                var value:NSString?
                var textScanner:Scanner = Scanner(string: textToScan)
                while textScanner.string != "" {
                    if (textScanner.string as NSString).substring(to: 1) == "\"" {
                        textScanner.scanLocation += 1
                        textScanner.scanUpTo("\"", into: &value)
                        textScanner.scanLocation += 1
                    } else {
                        textScanner.scanUpTo(",", into: &value)
                    }
    
                     values.append(value! as String)
    
                     if textScanner.scanLocation < textScanner.string.count {
                         textToScan = (textScanner.string as NSString).substring(from: textScanner.scanLocation + 1)
                     } else {
                         textToScan = ""
                     }
                     textScanner = Scanner(string: textToScan)
                }
    
                // For a line without double quotes, we can simply separate the string
                // by using the delimiter (e.g. comma)
            } else  {
                values = line.components(separatedBy: ",")
            }
    
            // Put the values into the tuple and add it to the items array
            let item = (values[0], values[1], values[2])
            items.append(item)
            print(item.1)
            print(item.2)
            print(item.3)
         }
     }
    

    It is just written in Swift 4, the original is from https://www.appcoda.com/core-data-preload-sqlite-database/

    0 讨论(0)
  • 2020-12-24 02:41

    Swift 5.0 .scanLocaion and .scanUpTo() were deprecated in iOS13. Here's a working version of Chhaileng's answer.

     func openCSV(fileName:String, fileType: String)-> String!{
        guard let filepath = Bundle.main.path(forResource: fileName, ofType: fileType)
            else {
                return nil
        }
        do {
            let contents = try String(contentsOfFile: filepath, encoding: .utf8)
    
            return contents
        } catch {
            print("File Read Error for file \(filepath)")
            return nil
        }
    }
    
     func parseCSV(){
    
        let dataString: String! = openCSV(fileName: "MeislinDemo", fileType: "csv")
        var items: [(String, String, String)] = []
        let lines: [String] = dataString.components(separatedBy: NSCharacterSet.newlines) as [String]
    
        for line in lines {
           var values: [String] = []
           if line != "" {
               if line.range(of: "\"") != nil {
                   var textToScan:String = line
                   var value:String?
                   var textScanner:Scanner = Scanner(string: textToScan)
                while !textScanner.isAtEnd {
                       if (textScanner.string as NSString).substring(to: 1) == "\"" {
    
    
                           textScanner.currentIndex = textScanner.string.index(after: textScanner.currentIndex)
    
                           value = textScanner.scanUpToString("\"")
                           textScanner.currentIndex = textScanner.string.index(after: textScanner.currentIndex)
                       } else {
                           value = textScanner.scanUpToString(",")
                       }
    
                        values.append(value! as String)
    
                    if !textScanner.isAtEnd{
                            let indexPlusOne = textScanner.string.index(after: textScanner.currentIndex)
    
                        textToScan = String(textScanner.string[indexPlusOne...])
                        } else {
                            textToScan = ""
                        }
                        textScanner = Scanner(string: textToScan)
                   }
    
                   // For a line without double quotes, we can simply separate the string
                   // by using the delimiter (e.g. comma)
               } else  {
                   values = line.components(separatedBy: ",")
               }
    
               // Put the values into the tuple and add it to the items array
               let item = (values[0], values[1], values[2])
               items.append(item)
               print(item.0)
               print(item.1)
               print(item.2)
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-24 02:44

    What you want to do is splitting up the string in rows and then into columns (basically a two dimensional array of Strings). Swift already provides the components method for that on String structs.

    func csv(data: String) -> [[String]] {
        var result: [[String]] = []
        let rows = data.components(separatedBy: "\n")
        for row in rows {
            let columns = row.components(separatedBy: ";")
            result.append(columns)
        }
        return result
    }
    

    Then you can access any value via:

    var data = readDataFromCSV(fileName: kCSVFileName, fileType: kCSVFileExtension)
    data = cleanRows(file: data)
    let csvRows = csv(data: data)
    print(csvRows[1][1]) //UXM n. 166/167.
    
    0 讨论(0)
提交回复
热议问题