Kotlin getValue для строки, содержащей слово / слова, игнорируя регистр Upper или Lower и пробел - PullRequest
0 голосов
/ 10 мая 2018

Я создал список из файла.

Список содержит список, который выглядит следующим образом

(redTomatoes, 47.50) (greenapple, 23.75) (yellowBananas, 17)

и т. Д.

        var value = versionsList.getValue("banana")
        println("This is the value $value")

Приведенный выше код не будет повторять значение, поскольку оно не совпадает точно.Я не могу добавить ignoreCase или содержит с .getValue

Можно ли искать строку, содержащую слово, игнорируя регистр, пробел?

Нужно ли создавать какой-то цикл дляпроверить все возможные комбинации, чтобы получить значение?

Спасибо

1 Ответ

0 голосов
/ 11 мая 2018

Можно ли искать строку, содержащую слово, игнорируя регистр и пробел?

Это возможно , но это не то, что может бытьсделано без перебора всех элементов.

Нужно ли создавать какой-то цикл для проверки всех возможных комбинаций для получения значения?

Так что да, цикл некоторыхсортировка необходима, но тестирование всех возможных комбинаций немного экстремально.Предпочтительным способом было бы использовать .toLowerCase() на любой строке, прежде чем поместить ее на карту, даже если это не полностью устранит неоднозначность формата ключей.Но даже без такого изменения входных данных его можно решить.

Предлагаемое решение

С учетом таких входных данных, как

val fruits: Map<String, Double> = mapOf(
                "redTomatoes" to 47.50,
                "greenapple" to 23.75,
                "yellowBananas" to 17.0
        )

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

fun String.toLowerCaseWithoutWhiteSpace() = this.toLowerCase().replace(Regex("\\s+"), "")

Но так как мы не можем использовать .getValue() на нашей карте для этого, нам нужно написать собственную функцию для этого.

fun <T> Map<String, T>.getLike(key: String): T?
{
    val transformed = key.toLowerCaseWithoutWhiteSpace()
    return this
            .asSequence()
            // Change the keys in the map so they are also lower case and without whitespace
            .map { it.key.toLowerCaseWithoutWhiteSpace() to it.value}
            // Take the first entry where the key matches
            .firstOrNull { (keyInMap, _) ->
                keyInMap == transformed
            }
            // Return the value from the entry
            ?.second
}

И затем мы можем использовать следующее для доступа к нужным значениям

fruits.getLike("yellow bananas")
fruits.getLike("green apple")
fruits.getLike("red tomatoes")

Это, конечно, приводит к снижению производительности, доступ к нужному значению будет иметь временную сложность.O (N) вместо O (1).Это может быть хорошо для карты меньшего размера, но если на вашей карте будет много элементов, вы можете рассмотреть возможность обработки элементов перед их вставкой в ​​карту, или, если это невозможно, создать новую карту, если все ключи имеютбыл преобразован, как я сделал выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...