#kotlin
#котлин
Вопрос:
Я пытаюсь объединить значения с двух карт в Kotlin, но, похоже, не могу найти онлайн-решение для этого. Например, у меня есть эти два объекта карты, которые имеют вложенные карты, как показано ниже.
Первый: {settings={exit={exitMessage=message0}}, 2=2}
во — вторых: {settings={exit={differentMessage=message1, secondMessage=message2}}, 2=zebra}
Как вы можете видеть, есть некоторые одинаковые клавиши (например settings
, и exit
), но иногда клавиши разные. Мне интересно, как я могу объединить два объекта карты, чтобы конечный результат был таким
{settings={exit={exitMessage=message0, differentMessage=message1, secondMessage=message2}}, 2=zebra}
Мы не можем просто «добавить» две карты вместе, потому что Kotlin переопределит объекты карты
Например, если мы добавим два объекта выше, как first second
, конечный результат будет просто
{settings={exit={differentMessage=message1, secondMessage=message2}}, 2=zebra}
поскольку exit
карта во втором имеет приоритет над объектом exit
карты в первом.
Комментарии:
1. Это то, что я пытаюсь выяснить прямо сейчас. В kotlin, когда вы добавляете два объекта карты вместе (например, если я добавляю
first
иsecond
), если ключи совпадают (в моем примере ключ равенsettings
), Kotlin выбирает значениеsecond
maps в keysettings
для объединенной карты2. Ой, ой, я прочитал не тот бит. Игнорируйте то, что я только что сказал.
3. Являются ли карты изменяемыми? Было бы намного проще, если бы они были.
4. Да, карты изменчивы
Ответ №1:
Вы можете попробовать сначала сгладить обе карты:
settings.exit.exitMessage=message0
2=2
settings.exit.differentMessage=message1
settings.exit.secondMessage=message2
2=zebra
Затем после объединения карт вы получаете следующее:
settings.exit.exitMessage=message0
settings.exit.differentMessage=message1
settings.exit.secondMessage=message2
2=zebra
А затем просто перестройте карту снова, взорвав ключи.
Полный пример кода здесь: https://pl.kotl.in/p9BaUVOF3
Выравнивание карты
fun flatten(source: Map<String, Any>, target: HashMap<String, Any>, prefix: String = "") {
for (entry in source) {
var fullKey = if (prefix.length > 0) prefix "." entry.key else entry.key
if (entry.value is Map<*, *>) {
flatten(entry.value as Map<String, Any>, target, fullKey)
continue
}
target.put(fullKey, entry.value)
}
}
Взрыв сплющенной карты
fun explode(source: Map<String, Any>, target: HashMap<String, Any>) {
for (entry in source) {
var targetMap = target
var keySegments = entry.key.split(".")
// Rebuild the map
for (keySegment in keySegments.dropLast(1)) {
if (targetMap.containsKey(keySegment)) {
var value = targetMap.get(keySegment)
if (value is Map<*, *>) {
targetMap = value as HashMap<String, Any>
continue
}
}
var newNestedMap = HashMap<String, Any>()
targetMap.put(keySegment, newNestedMap)
targetMap = newNestedMap
}
// Put values into it
targetMap.put(keySegments.last(), entry.value)
}
}
Комментарии:
1. Как мне выровнять карты? Кроме того, что вы подразумеваете под взрывом ключей
2. Я не знаю, в частности, для Kotlin, но в целом вы можете сгладить карту, пройдя ее рекурсивно и сохранив найденные значения на другой карте, используя ключи, составленные из ключей с исходной карты. Я попробую немного обновить ответ. Разрыв карты — это обратный процесс.
3. Я добавил подсказку по выравниванию к ответу (хотя кодирование на моем мобильном телефоне).
4. @Mkim175 Я обновил ответ и включил рабочий пример кода.