🗒 Задача¶
Представим, что мы получили массив ингредиентов. Программа должна распечатать весь список ингредиентов, затем заменить нужный ингредиент на новый по желанию пользователя. После этого программа должна показать обновленный список.
-
создай массив со списком ингредиентов и напечатай его в консоль;
-
запроси у пользователя информацию об ингредиенте, который он хочет заменить;
-
если пользователь ввел ингредиент, которого нет в списке, вывести соответствующее сообщение;
-
если есть, запроси ингредиент, который пользователь хотел бы добавить;
-
выведи обновленный список с сообщением: “Готово! Вы сохранили следующий список: [список_ингредиентов]”.
❌ Ошибки¶
- используют списки вместо массивов (поэтому используют add() вместо обращения по индексу)
✏️ Комментарии¶
Отлично! На самом деле этот код уже хорош, но хочу подсветить один неочевидный момент, который в данном простом случае ни на что не влияет, но может пригодиться в более сложных ситуациях.
Конструкции `ingredients.contains(ingredientToReplace)` и `ingredients.indexOf(ingredientToReplace)` внутри себя осуществляют проход по всему списку циклом. То есть, ты два раза делаешь перебор всех элементов цикла. Можно оптимизировать, сделав за if-ом `indexOf`, сохранить в переменную и делать сравнение с `-1` (это то, что возвращает `indexOf` если ничего не нашел). А далее использовать тот же индекс для замены ингредиента
Явное приведение к строке тут избыточно. Так как readln() всегда и так уже возвращает String. Можно провалиться в цепочку деклараций метода и убедиться, что всегда возвращаемое значение будет строкой.
Также как и `null` эта переменная стать не может. Однако, может прийти пустая строка. Для этого можно добавить проверку с помощью экстеншен функции `isEmpty()` или `isNotEmpty()`
Обрати внимание: `contains` и `indexOf` делают одно и тоже - пробегаются по списку и ищут элемент. По идее нам должно хватить `indexOf` и переменной
Есть несколько способов искать элемент в списке, ты используешь два: `receptOne.contains` и `receptOne.indexOf`. Давай `contains` заменим тоже на сравнение индекса, и будем один раз делать `receptOne.indexOf` в переменную
Предлагаю убрать цикл. Нет необходимости перебирать, достаточно только проверять наличие ключевым словом `in`
В условии можно использовать более короткий метод определения наличия элемента в списке. С помощью `in`
Предлагаю сразу обращаться к нужному элементу, находя его индекс с помощью `indexOf`. И по этому индексу перезаписывать элемент пользователя
Из-за разорванного условия сильно ухудшилась читаемость. Большая концентрация условий на одну строку
Можно сократить при помощи arrayOfIngredients.forEach { ... }. Так код станет более универсальным - не будет зависеть от количества ингредиентов в arrayOfIngredients
Способ рабочий, но выглядит довольно костыльно) Чтобы из массива создать строку, посмотри сигнатуру метода joinToString(). В нем есть параметры, которые позволяют создать строку сразу с нужными разделителями вот так: `println(arrayOfIngredients.joinToString(", ", "", "."))`
Название итерируемой переменной лучше писать более релевантное для улучшения читаемости кода. Будущие коллеги скажут тебе спасибо!
🧾 Решение¶
//Вариант для зануд – без in, чтобы избежать лишних проходов по циклу
fun main() {
val ingredients = mutableListOf("Мука", "Сахар", "Яйца", "Молоко", "Разрыхлитель")
println("Исходный список ингредиентов: $ingredients")
print("Введите ингредиент для замены: ")
val toReplace = readln()
val index = ingredients.indexOf(toReplace) // << тут идем по циклу 1 раз
if (index >= 0) {
print("Введите новый ингредиент: ")
val newIngredient = readln()
ingredients[index] = newIngredient
println("Готово! Вы сохранили следующий список: $ingredients")
} else {
println("Ингредиент '$toReplace' не найден в списке.")
}
}
fun main() {
val ingredients = mutableListOf("Мука", "Сахар", "Яйца", "Молоко", "Разрыхлитель")
println("Исходный список ингредиентов: $ingredients")
print("Введите ингредиент для замены: ")
val toReplace = readln()
if (toReplace in ingredients) {
print("Введите новый ингредиент: ")
val newIngredient = readln()
ingredients[ingredients.indexOf(toReplace)] = newIngredient
println("Готово! Вы сохранили следующий список: $ingredients")
} else {
println("Ингредиент '$toReplace' не найден в списке.")
}
}