Replace occurrences в масиве

Содержимое файла.

1. @NAME1  прыгает через @NAME2#
2. Все игроки молчат.#
3. @NAME1 делает 10 отжиманий.#

Я должен начать с первой строки, когда я нахожу в строке @NAME1 или @NAME 2 я заменяю именами которые вводят игроки ранее. Если нет @NAME1, то вывожу строку и ничего не меню. И так далее.

Раньше я мог считать строку с файла, затем заменить имена в этой строке. При каждом нажатии на кнопку, я получал рандомную строку.

Метод выглядел вот так.

func getDataFromFile(name: String , type:String) -> String {
    let pathFile = Bundle.main.path(forResource: name, ofType: type)
    let contentString = try! NSString(contentsOfFile: pathFile!, encoding: String.Encoding.utf8.rawValue)
    let  randomContent = contentString.components(separatedBy: ["#"]).randomElement()!.replacingOccurrences(of: "\"", with: "")
    return randomContent
}

Затем нужно было переделать чтобы считывалось последвовательно, и метод был переделан вот так.

func getDataFromFile(name: String , type: String) -> [String] {
    let pathFile = Bundle.main.path(forResource: name, ofType: type)
    let contentString = try! NSString(contentsOfFile: pathFile!, encoding: String.Encoding.utf8.rawValue)
    let fullContent = contentString.components(separatedBy: ["#"]).map { $0.replacingOccurrences(of: "\"", with: "") }
    return fullContent
}

let stringsFromFile = getDataFromFile(name: "file", type: "txt")
stringsFromFile.forEach {
   $0.replacingOccurrences(of: "@NAME1", with: firstName!, options: .literal, range: nil)
   $0.replacingOccurrences(of: "@NAME2", with: secondName!, options: .literal, range: nil)

      playerLabel.text = $0
}

Теперь почему то мне показывает одну строку без имён и когда я пытаюсьпоказать следующую строку, ничего не происходит.


Ответы (2 шт):

Автор решения: schmidt9

Я проверил ваш пример, в нем были ошибки

  • строки не отображались, так как в них содержались переносы строки \n в начале строк, соответственно при выводе в лейбл сама строка переносилась и была не видна.
  • исправлена замена шаблонов в строках

Также я добавил удаление пустых строк.

Помимо этого здесь приведена логика показа и последующего удаления строк из массива при каждом нажатии на кнопку

class ViewController: UIViewController {

    @IBOutlet var playerLabel: UILabel!

    var stringsFromFile = [String]()
    let firstName = "Name 1"
    let secondName = "Name 2"

    override func viewDidLoad() {
        super.viewDidLoad()

        loadStrings()
    }

    func loadStrings() {
        stringsFromFile = getDataFromFile(name: "file", type: "txt")
        stringsFromFile = stringsFromFile.map {
            var result = $0.replacingOccurrences(of: "@NAME1", with: firstName, options: .literal, range: nil)
            result = result.replacingOccurrences(of: "@NAME2", with: secondName, options: .literal, range: nil)
            return result
        }
    }

    func getDataFromFile(name: String , type: String) -> [String] {
        let pathFile = Bundle.main.path(forResource: name, ofType: type)
        let contentString = try! NSString(contentsOfFile: pathFile!, encoding: String.Encoding.utf8.rawValue)
        let fullContent = contentString.components(separatedBy: ["#"]).map { $0.replacingOccurrences(of: "\n", with: "") }.filter { !$0.isEmpty }
        return fullContent
    }

    @IBAction func nextRecordButtonTouchUpInside(_ sender: UIButton) {
        guard let firstString = stringsFromFile.first else {
            playerLabel.text = ""
            return
        }

        playerLabel.text = firstString
        stringsFromFile.removeFirst()
    }

}
→ Ссылка
Автор решения: Roman Podymov

Объявите stringsFromFile как свойство Вашего потомка UIViewController:

let stringsFromFile = Self.getDataFromFile(name: "file", type: "txt")

Для того, чтобы устранить ошибки компиляции в данной строчке, сделайте getDataFromFile(name:type:) статической:

static func getDataFromFile(name: String , type: String) -> [String] {
    let pathFile = Bundle.main.path(forResource: name, ofType: type)
    let contentString = try! NSString(contentsOfFile: pathFile!, encoding: String.Encoding.utf8.rawValue)
    let fullContent = contentString.components(separatedBy: ["#"]).map { $0.replacingOccurrences(of: "\"", with: "") }
    return fullContent
}

Добавьте новой свойство var currentStringsFromFileIndex = 0 для отслеживания текущей позиции в массиве stringsFromFile.

Насколько я понял, у вас есть кнопка, нажимая на которую должна обрабатываться следующая строка из stringsFromFile. Тогда у функции для обработки нажатия должен быть такой код:

@objc func onButtonTap(sender: UIButton) {
    guard stringsFromFile.indices.contains(currentStringsFromFileIndex) else { // Проверяем, существует ли элемент с индексом currentStringsFromFileIndex
        return
    }
    playerLabel.text = stringsFromFile[currentStringsFromFileIndex]
        .replacingOccurrences(of: "@NAME1", with: firstName!, options: .literal, range: nil)
        .replacingOccurrences(of: "@NAME2", with: secondName!, options: .literal, range: nil)
    currentStringsFromFileIndex += 1
}

Теперь при нажатии на кнопку у playerLabel будет меняться отображаемый текст.

→ Ссылка