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 шт):
Я проверил ваш пример, в нем были ошибки
- строки не отображались, так как в них содержались переносы строки
\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()
}
}
Объявите 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 будет меняться отображаемый текст.