Разбор аргументов основной функции в функциональном стиле для Kotlin - PullRequest
0 голосов
/ 27 декабря 2018

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

В Интернете сейчас есть какой-то парсер аргументов Kotlin, например GitHub: xenomachina / kotlin-argparser , GitHub:Kotlin / kotlinx.cli или GitHub: ajalt / clikt .Однако я не хочу добавлять такую ​​огромную папку в мой (возможно) маленький проект.То, что я хочу, - это простое и чистое решение, например, просто функция с «плавной» реализацией в стиле потока.Вместо этого все эти проекты содержат несколько файлов.

Я думаю только о том, что нужно просто преобразовать параметр командной строки в Map<String, List<String>>, использовать map.containsKey(), чтобы получить параметр no_argument, и использовать map[key] для получения required_argument параметра.

Например, список параметров командной строки

-a -b c -d e f g -h --ignore --join k --link m n o -p "q r s"

будет проанализирован как:

{-a=[], -b=[c], -d=[e, f, g], -h=[], --ignore=[], --join=[k], --link=[m, n, o], -p=[q r s]}

или, скажем,

mapOf(
    "-a" to listOf(), // POSIX style, no argument
    "-b" to listOf("c"), // POSIX style, with single argument
    "-d" to listOf("e", "f", "g"), // POSIX style, with multiple argument
    "-h" to listOf(), // POSIX style, no argument
    "--ignore" to listOf(), // GNU style, no argument
    "--join" to listOf("k"), // GNU style, with single argument
    "--link" to listOf("m", "n", "o"), // GNU style, with multiple argument
    "-p" to listOf("q r s") // POSIX style, with single argument containing whitespaces
)

Ответы [ 3 ]

0 голосов
/ 27 декабря 2018

Вот еще одна реализация:

fun getopt(args: Array<String>): Map<String, List<String>>
{
    var last = ""
    return args.fold(mutableMapOf()) {
        acc: MutableMap<String, MutableList<String>>, s: String ->
        acc.apply {
            if (s.startsWith('-'))
            {
                this[s] = mutableListOf()
                last = s
            }
            else this[last]?.add(s)
        }
    }
}

Непосредственно создайте структуру карты, но для добавления следующих аргументов следует сохранить ссылку на последний параметр.Эта функция не , поэтому потоковая, а просто требует 1 проход данных.И он просто отбрасывает ведущие аргументы без предыдущего параметра.

0 голосов
/ 03 января 2019

Что ж, мое решение включает в себя неизменность и сворачивание с параметром last.

fun main(args: Array<String>) {
    val map = args.fold(Pair(emptyMap<String, List<String>>(), "")) { (map, lastKey), elem ->
        if (elem.startsWith("-"))  Pair(map + (elem to emptyList()), elem)
        else Pair(map + (lastKey to map.getOrDefault(lastKey, emptyList()) + elem), lastKey)
    }.first

    println(map)

    val expected = mapOf(
        "-a" to emptyList(),
        "-b" to listOf("c"),
        "-d" to listOf("e", "f", "g"),
        "-h" to emptyList(),
        "--ignore" to emptyList(),
        "--join" to listOf("k"),
        "--link" to listOf("m", "n", "o"),
        "-p" to listOf("q r s"))

    check(map == expected)
}

Выход

{-a=[], -b=[c], -d=[e, f, g], -h=[], --ignore=[], --join=[k], --link=[m, n, o], -p=[q r s]}

Это также обрабатывает случай, когдапервые аргументы являются параметрами, и вы можете получить к ним доступ в map[""]

0 голосов
/ 27 декабря 2018

Вот моя реализация.

fun getopt(args: Array<String>): Map<String, List<String>> = args.fold(mutableListOf()) {
    acc: MutableList<MutableList<String>>, s: String ->
    acc.apply {
        if (s.startsWith('-')) add(mutableListOf(s))
        else last().add(s)
    }
}.associate { it[0] to it.drop(1) }

Используйте fold для группировки параметров с соответствующими им аргументами (то есть конвертируйте [-p0 arg0 arg1 -p1 arg2] в [[-p0, arg0, arg1], [-p1, arg2]]), затем associate в Map.Эта функция потоковая, но требует 2 передачи данных.Также, если есть несколько ведущих аргументов без предыдущего параметра, это вызовет исключение.

...