Проблемы с чтением в текстовом файле в нужный формат массива - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь сжать приложение, над которым я работаю, это большой каталог с большим количеством UIViewControllers и UITableViews.

Мой план состоит в том, чтобы переписать приложение, которое будет использовать одноразовое использование UIViewController с UITableView, которое будет загружать данные из текстовых файлов по мере необходимости во время выполнения или после него. TXT-файлы будут считываться во время выполнения или после него, вместо того, чтобы собирать все файлы Swift перед этим.

В настоящее время моему приложению требуется несколько минут для сборки / компиляции каждый раз, когда я вносю изменения в проект. Поэтому я надеюсь, что, прочитав и проанализировав текстовые файлы по мере необходимости, я смогу создать приложение всего за несколько секунд.

Ниже приведена моя попытка прочитать и сгенерировать необходимый массив «конфет», используя приведенный ниже пример текстового файла (candyTextFile.txt). Пожалуйста, смотрите закомментированные строки в классе, MasterViewController, для сообщения об ошибке и кода, который я пытаюсь вывести как массив конфет.

Обратите внимание, я сократил строки в моем текстовом файле до трех строк. В моем последнем приложении будет много похожих текстовых файлов, каждый из которых будет содержать несколько сотен строк.

Я все еще относительно новичок в Swift, поэтому прошу прощения, если я упустил что-то простое здесь, и если я использую / не использую подходящую терминологию.

Я верю, что термин CandySearch только от названия проекта (см. здесь ). Я не уверен, почему он выводится в массиве candies. Кроме того, теперь я вижу, что мой текущий myArray установлен как класс. Как я могу превратить его в массив?

Вот мой соответствующий код в моих MasterViewController.swift,

class MasterViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var candies = [myArray]()
    var evenIndicies = [String]()
    var oddIndicies = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        setUpArray()
    }

    private func setUpArray() {
        if let filepath = Bundle.main.path(forResource: "candyTextFile", ofType: "txt") {
            do {
                // let contents = try String(contentsOfFile: "candyTextFile", encoding: String.Encoding.utf8)
                let contents = try String(contentsOfFile: filepath)
                let lines_separatedBy_n : [String] = contents.components(separatedBy: "\n")
                let string = lines_separatedBy_n.map { String($0) }.joined(separator: ", ")
                print("string: \(string)")
                let lines_separatedBy_comma : [String] = string.components(separatedBy: ", ")
                print("lines_separatedBy_comma: \(lines_separatedBy_comma)")

                for (index, element) in lines_separatedBy_comma.enumerated() {
                    if index % 2 == 0 {
                        evenIndicies.append(element)
                        print("evenIndicies: \(evenIndicies)")

                    } else {
                        oddIndicies.append(element)
                        print("oddIndicies: \(oddIndicies)")
                    }
                }
                evenIndicies.remove(at: evenIndicies.count - 1) // the -1 removes the nil element, "", in the array. For some reason, there is a fourth element, "", in the evenIndicies array. Therefore, I remove it by subtracting one index so I get the three indexes. My in project txt file is four lines long where the fourth line is empty. I think this is why it is showing up "" for the fourth index.
                print("evenIndicies outside for-loop: \(evenIndicies)")
                print("oddIndicies outside for-loop: \(oddIndicies)")
                candies = [myArray(category: evenIndicies, name: oddIndicies)]  // 

                print("candies: \(candies)") 
           // This prints as the following:
           // candies: [CandySearch.myArray]

           // HOWEVER, I am trying to get it to print as: 
           // [CandySearch.myArray(category: "Chocolate", name: "Chocolate Bar"), CandySearch.myArray(category: "Chocolate", name: "Chocolate Cookie"), CandySearch.myArray(category: "Hard", name: "Lollipop")]




            } catch let error as NSError {
                print(error.localizedDescription)
            }
        }
    }
}

class myArray {
    let category: [String]
    let name: [String]
    init(category: [String], name: [String]) {
        self.category = category
        self.name = name
    }
}

В моем текстовом файле candyTextFile.txt, у меня есть

Chocolate, Chocolate Bar
Chocolate, Chocolate Cookie
Hard, Lollipop

1 Ответ

0 голосов
/ 04 января 2019

Я попробую сделать это, предполагая, что вы хотите взять информацию из текстового файла и получить массив ваших конфетных продуктов. На данный момент у вас есть myArray класс, который немного напоминает какую-то вещь Франкенштейна. Он содержит все категории и имена в двух отдельных массивах внутри одного экземпляра этого класса. Затем вы помещаете его в массив с именем candies. Это все выглядит как тупик, если я не понимаю ваши требования. (Может быть, и я.) Но при условии, что я хотя бы наполовину прав ...

Вам нужен набор конфет, поэтому давайте создадим новый класс, в котором будет одна конфета.

class Candy {
    let category: String!
    let name: String!

    init(category: String, name: String) {
        self.category = category
        self.name = name
    }
}

Это похоже на то, что у вас уже было, но когда вы создаете экземпляр экземпляра Candy, он будет содержать информацию об одной конфете. Примечание: имена классов начинаются с заглавной буквы по соглашению.

Вы хотите получить массив конфет, поэтому давайте изменим определение вашего candies массива.

var candies: [Candy] = []

Осталось только изменить цикл for in для извлечения данных о конфетах (категории и имени) на один цикл, создать новый экземпляр Candy и заполнить его перед добавлением в candies.

for (index, element) in lines_separatedBy_comma.enumerated() {
   var newCategory = ""
   var newName = ""
   if index % 2 == 0 {
      newCategory = element
   } else {
      newName = element
   }
   let newCandy = Candy(category: newCategory, name: newName)
   candies.append(newCandy)
}

У вас нет какой-либо проверки в вашем коде, которая бы обрабатывала любые ошибки / неправильное форматирование в вашем текстовом файле, поэтому я предполагаю, что вы абсолютно уверены, что он состоит из пар данных без свободных концов и т. Д. I вижу, вы удалите последний элемент evenIndices по какой-то причине. Я не уверен, почему, поэтому я не справился с этим.

Теперь ваш массив candies должен содержать кучу объектов Candy, поэтому для вывода их на консоль вы можете сделать что-то вроде этого.

for candy in candies {
   print("category: \(String(describing: candy.category)), name: \(String(describing: candy.name))")
}

Дайте мне знать, если я все еще не попал в цель.

РЕДАКТИРОВАТЬ ********************************************** ********** РЕДАКТИРОВАТЬ

Я посмотрел учебник по RW, который вы связали.

В учебнике для элемента Candy используется struct, тогда как вы (и я) использовали класс. Я предполагаю, что вы все еще узнаете о значении и ссылочных типах Swift, так что не будем мутить воду здесь дальше. Достаточно сказать, что struct, вероятно, будет лучше в этом случае. print также обрабатывает их по-разному и, кажется, может искать внутри структур значения, тогда как, если вы явно не извлечете свойства (как в моем операторе печати for in, он просто выдаст вам список классов, как мы видели).

Я также отсортировал логику (это уродливо, и вы не должны делать это таким образом), чтобы вы могли по крайней мере увидеть, что она работает (по моде). Весь setupArray метод:

private func setupArray() {
     if let filepath = Bundle.main.path(forResource: "candyTextFile", ofType: "txt") {
         do {
             let contents = try String(contentsOfFile: filepath)
             let lines_separatedBy_n : [String] = contents.components(separatedBy: "\n")
             let string = lines_separatedBy_n.map { String($0) }.joined(separator: ", ")
             var lines_separatedBy_comma : [String] = string.components(separatedBy: ", ")

             // I've put this in to remove the last bit of the file that was causing the count to be one too high.
             // I'm guessing that's why you had something similar previously?
             lines_separatedBy_comma.removeLast()

             for (index, element) in lines_separatedBy_comma.enumerated() {
                 if index % 2 == 0 {
                     let newCategory = element
                     let newName = lines_separatedBy_comma[index + 1]
                     let newCandy = Candy(category: newCategory, name: newName)
                     candies.append(newCandy)
                 }
             }
             for candy in candies {
                 print("category: \(candy.category!), name: \(candy.name!)")
             }
             print("\ncandies: \(candies)")
         } catch let error as NSError {
             print(error.localizedDescription)
         }
     }
 }

Когда я использую:

class Candy {
    let category: String!
    let name: String!

    init(category: String, name: String) {
        self.category = category
        self.name = name
    }
}

вывод:

category: Chocolate, name: Chocolate Bar
category: Chocolate, name: Chocolate Cookie
category: Hard, name: Lollipop

candies: [FileTest.Candy, FileTest.Candy, FileTest.Candy]

Когда я использую: (после удаления принудительного развертывания из оператора печати)

struct Candy {
    let category : String
    let name : String
}

вывод:

category: Chocolate, name: Chocolate Bar
category: Chocolate, name: Chocolate Cookie
category: Hard, name: Lollipop

candies: [FileTest.Candy(category: "Chocolate", name: "Chocolate Bar"), FileTest.Candy(category: "Chocolate", name: "Chocolate Cookie"), FileTest.Candy(category: "Hard", name: "Lollipop")]

Видите ли вы, что ваш исходный код поместил все внутри одного myArray, но код выше (и на сайте RW) создает отдельные Candy элементы и сохраняет их все в candies? Это принципиальная разница в подходах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...