如果这样写问题解答,请告诉我。另外,我也期待更好的答案。我提供的两种解决方案都不完美。
现在Internet上有一些Kotlin参数解析器,例如GitHub: xenomachina/kotlin-argparser,GitHub: Kotlin/kotlinx.cli或GitHub: ajalt/clikt。但是我不想在我的(也许)小项目中添加这么大的文件夹。我想要的是一个简单干净的解决方案,例如一个函数,并带有“流利的”流样式实现。相反,这些项目都包含几个文件。
我的想法是,只需将命令行参数解析为Map<String, List<String>>
,使用map.containsKey()
获取no_argument
参数,然后使用map[key]
获取{ {1}}参数。
例如,命令行参数列表
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]}
答案 0 :(得分:2)
好吧,我的解决方案还涉及不可变性和使用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[""]
中访问它们
答案 1 :(得分:0)
这是我的实现方式。
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
)
使用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
。此功能正在流式传输,但需要2次数据传递。另外,如果某些前导参数不带前一个参数,则会导致异常。
答案 2 :(得分:0)
这是另一种实现方式:
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)
}
}
}
直接构造映射结构,但应保留最后一个参数的引用以添加下一个参数。此功能不是 so 流式传输,而只需要传递1次数据即可。而且,它只是简单地丢弃前导参数而没有前一个参数。