Шаг 115.
Основы Kotlin.
Списки и множества. Чтение файла в список

    На этом шаге мы рассмотрим пример заполнения списка из файла.

    Разнообразие украшает жизнь, и трактирщик знает, что посетители хотят богатого выбора в меню. На данный момент Dragons' Breath - это единственное, что продается в таверне. Настало время это исправить, добавив в меню больше блюд и напитков.

    Чтобы сэкономить время, мы подготовили меню в текстовом файле, который можно загрузить в NyetHack. Файл содержит несколько пунктов для меню в таком же формате, как описание напитка Dragons' Breath.

    Сначала создайте новую папку для данных: щелкните правой кнопкой мыши на проекте NyetHack в окне инструментов проекта и выберите New | Directory (риунок 1).


Рис.1. Создание новой папки

    Присвойте папке имя data.

    Создайте в папке data текстовый файл с именем tavern-menu-items.txt, поместив туда следующее меню:

shandy,Dragon's Breath,5.91
elixir,shirley temple,4.12
meal,goblet of la croix,1.22
desert dessert,pickled camel hump,7.33
elixir,iced boilermaker,11.22

    Теперь можно добавить в Tavern.kt код для чтения текста из файла в строку и вызвать split() для итоговой строки. Не забудьте добавить в начало файла Tavern.kt инструкцию import java.io.File.

import kotlin.math.roundToInt
import java.io.File

const val TAVERN_NAME = "Taernyl's Folly"

var playerGold = 10
var playerSilver = 10
val patronList = mutablelistOf("Eli", "Mordoc", "Sophie")
val menuList = File("data/tavern-menu-items.txt")
        .readText()
        .split("\n")
.   .   .   .


Рис.2. Чтение меню из файла (Tavern.kt)

    Вы использовали тип java.io.File для работы с конкретным файлом по указанному пути.

    Функция readText() в File возвращает содержимое файла в виде строки. Затем вызывается функция split(), чтобы разбить содержимое файла по символу перевода строки (представлен экранированной последовательностью '\n') и вернуть его как список.

    Теперь вызовите forEachIndexed() для menuList, чтобы вывести все элементы списка вместе с их индексами.

.   .   .   .
fun main() {
    .    .   .   .
    patronList.forEachIndexed { index, patron ->
        println("Good evening, $patron - you're #${index + 1} in line.")
        placeOrder(patron, "shandy,Dragon's Breath,5.91")
    }
    menuList.forEachIndexed { index, data ->
        println("$index : $data")
    }
}
.   .   .   .
}
Файл с проектом можно взять здесь.


Рис.3. Вывод разнообразного меню (Tavern.kt)

    Запустите Tavern.kt. Вы увидите содержимое меню, загруженное в список:

  0 : shandy,Dragon's Breath,5.91
  1 : elixir,Shirley's Temple,4.12
  2 : meal,goblet of LaCroix,1.22
  3 : desert dessert,pickled camel hump,7.33
  4 : elixir,iced boilermaker,11.22


Рис.4. Результат работы приложения

    Теперь, получив menuList, сделайте так, чтобы каждый посетитель что-нибудь заказал, выбирая случайное блюдо из меню.

.   .   .   .
fun main() {
    .    .   .   .
    patronList.forEachIndexed { index, patron ->
        println("Good evening, $patron - you're #${index + 1} in line.")
        placeOrder(patron, menuList.shuffled().first())
    }
    menuList.forEachIndexed { index, data ->
        println("$index : $data")
    }
}
.   .   .   .
}
Файл с проектом можно взять здесь.


Рис.5. Выбор случайных позиций из меню (Tavern.kt)

    Запустите Tavern.kt. Вы увидите, что каждый посетитель сделал заказ на случайную позицию из меню.


Рис.6. Результат работы приложения


Отметим, что если у вас результат работы приложения отличается от приведенного на рисунке 6, то попробуйте использовать вместо символа-разделителя "\n" комбинацию "\r\n". Это вызвано особенностями обработки разделителей строк операционной системой.

    На следующем шаге мы рассмотрим деструктуризацию.




Предыдущий шаг Содержание Следующий шаг