🗒 Задача¶
Создай класс Chat, который реализует обсуждение в мессенджере, аналогичному Discord. Класс должен иметь следующие методы:
-
addMessage()— добавляет обычное сообщение в чат, принимает на вход текст и автора сообщения; -
addThreadMessage()— добавляет сообщение в тред к предыдущему сообщению (для начала обсуждения), дополнительно принимает на входparentMessageIdдля идентификации сообщения, под которым создается ветка обсуждения;
Сообщения чата должны храниться в списке, в классе Chat. Для создания сообщений соответствующих типов используй классы Message и ChildMessage в соответствующей иерархии. У каждого типа сообщения должен быть id.
printChat()— печатает все сообщения чата. Если создано дочернее сообщение, необходимо применить для вывода табуляцию и печатать его под родительским сообщением. ИспользуйgroupBy()для группировки сообщений поparentMessageId, если сообщение является экземпляромChildMessage, или поidесли это обычное сообщение.
❌ Ошибки¶
- вместо символа
\tиспользуют набор из нескольких пробелов
✏️ Комментарии¶
Рекомендую использовать специальный символ для таба `\t`. Применяется по аналогии с символом переноса строки.
`groupBy` возвращает Map. Map возвращает нуллябельный тип значения. Оператор `!!` (утверждение “это не null”) не рекомендуется использовать, так как если в это место придет таки null – программа упадет с ошибкой, которую будет относительно сложно найти в большом проекте. Предлагаю добавить более безопасную проверку на null.
// объяснение
Для простоты понимания я предлагаю использовать 2 списка: список сообщений и список дочерних сообщений (они добавляются в методе addThreadMessage).
Далее нам нужно только сгруппировать только дочерние сообщения по parentMessageId.
И наконец нужно провернуть правильный вывод этих сообщений. Можно использовать два цикла: один выводит базовое сообщение, а второй цикл проходит по ключам в виде id базового сообщения и печатает сообщение треда с отступом (табуляцией)
🧾 Решение¶
class Chat {
val messageList: MutableList<Message> = mutableListOf()
val childMessageList: MutableList<ChildMessage> = mutableListOf()
fun addMessage(_author: String, _text: String) {
val newMessage = Message(
id = messageList.size,
author = _author,
text = _text,
)
messageList.add(newMessage)
}
fun addThreadMessage(_author: String, _text: String, _parentMessageId: Int) {
val threadMessage = ChildMessage(
id = messageList.size,
author = _author,
text = _text,
parentMessageId = _parentMessageId,
)
childMessageList.add(threadMessage)
}
fun printChat() {
val groupedChildMessage: Map<Int, List<ChildMessage>> =
childMessageList.groupBy { it.parentMessageId }
messageList.forEach { baseMessage ->
println("${baseMessage.author}: ${baseMessage.text}")
groupedChildMessage[baseMessage.id]?.forEach { childMessage ->
println("\t${childMessage.author}: ${childMessage.text}")
}
}
}
}
open class Message(val id: Int, val author: String, val text: String)
class ChildMessage(id: Int, author: String, text: String, val parentMessageId: Int) : Message(id, author, text)
fun main() {
val chat = Chat()
chat.addMessage("Dima", "Привет 1")
chat.addThreadMessage("None", "Привет 2", chat.messageList[0].id)
chat.addThreadMessage("ANone", "Привет 3", chat.messageList[0].id)
chat.addMessage("Dima1", "Привет 2")
chat.addMessage("Dima2", "Привет 3")
chat.addThreadMessage("ANone", "Привет 3", chat.messageList[1].id)
chat.addThreadMessage("ANone", "Привет 3", chat.messageList[1].id)
chat.addThreadMessage("ANone", "Привет 3", chat.messageList[1].id)
chat.addThreadMessage("ANone", "Привет 3", chat.messageList[1].id)
chat.printChat()
}
open class Message(val id: Int, val author: String, val text: String)
class ChildMessage(id: Int, author: String, text: String, val parentMessageId: Int) : Message(id, author, text)
class Chat {
private val messages = mutableListOf<Message>()
private var nextMessageId = 0
fun addMessage(author: String, text: String) {
messages.add(Message(nextMessageId++, author, text))
}
fun addThreadMessage(parentMessageId: Int, author: String, text: String) {
if (messages.any { it.id == parentMessageId }) {
messages.add(ChildMessage(nextMessageId++, author, text, parentMessageId))
} else {
println("Parent message with id $parentMessageId not found.")
}
}
fun printChat() {
val threadMap: Map<Int, List<Message>> = messages.groupBy {
if (it is ChildMessage)
it.parentMessageId
else
it.id
}
threadMap.forEach { (_, messageList) ->
messageList.forEach { message ->
val tab = if (message is ChildMessage) "\t" else ""
println("$tab${message.id}. ${message.author}: ${message.text}")
}
}
}
}
fun main() {
val chat = Chat()
chat.addMessage("Alice", "Hello everyone!")
chat.addMessage("Bob", "Hi Alice!")
chat.addThreadMessage(0, "Charlie", "Hey Alice!")
chat.addThreadMessage(0, "Charlie", "Hey Alice!")
chat.addThreadMessage(0, "Charlie", "Hey Alice!")
chat.addThreadMessage(1, "Dave", "Hi Bob!")
chat.printChat()
}