https://kotlinlang.org logo
Title
c

chb0kotlin

06/20/2017, 8:10 PM
Is there a slick kotlin way of handling this? I have a series of cmdline args like "--root /home/foo --root /other/dir --algo MD5" and I want to turn them into a Map<String,List<String>>
t

tulio

06/20/2017, 8:25 PM
chb0kotlin: Have you considered using some lib to handle CLI params?
d

damian

06/20/2017, 8:35 PM
If so, I'd definitely recommend JCommander 😒imple_smile: http://jcommander.org/#_kotlin
👍 1
c

chb0kotlin

06/20/2017, 8:57 PM
I am intentionally not using any libraries - normally I would but this is for demonstrating kotlins capabilities as a language. I need to take the commandline args and turn it into necessary types to pass to a contructor:
public DeDup(Set<File> roots, String hashAlgo, Set<String> fileTypes) {
        this.roots = roots;
        this.hashAlgo = hashAlgo;
        this.fileTypes = fileTypes;
    }
x

xenomachina

06/20/2017, 9:38 PM
There are lots of corner cases to parsing command line args. eg, what happens if number of arguments is odd?
(shameless plug) kotlin-argparser would make parsing those options pretty easy:
class Args(parser: ArgParser) {
    val root by parser.adding("directories to search")
    val algo by parser.storing("hash algorithm")
    val fileTypes by parser.adding("file types to process",
            initialValue = mutableSetOf<String>()) { this }
}
c

cedric

06/21/2017, 2:03 AM
@chb0kotlin I respect your decision not to use any library but if you have any JCommander question, ask away. I'm using it with Kotlin without any efforts, although it's obviously not an idiomatically Kotlin library
t

tulio

06/21/2017, 7:09 PM
@chb0kotlin here a snippet to start with (just the happy path) :
val (keys, values) = args.partition { it.startsWith("--") } val result = keys.zip(values) .groupBy { it.first } .map { it.key to it.value.map { it.second } } .toMap()
Assuming that args is a Array<String>
c

chb0kotlin

06/21/2017, 8:49 PM
I never thought to use partition. I am gonna have to give this a try.
t

tulio

06/22/2017, 12:07 AM
@chb0kotlin I thought in a much more elegant solution:
args.partition { it.startsWith("--") } .let { it.first.zip(it.second) } .groupBy( {it.first}, {it.second} )
c

chb0kotlin

06/22/2017, 1:25 AM
WOW!
c

cedric

06/22/2017, 1:26 AM
Note that this will obviously fail if the command you're parsing is not using an exact even number of args
t

tulio

06/22/2017, 2:12 AM
Exactly... As I said, this cover only the happy path.
c

chb0kotlin

06/22/2017, 4:01 PM
That's all ok. It's for demonstrating how Kotlin can save lines of code and provide clarity. The application it's replicating doesn't handle commandline args any better
Def appreciate it. If I can get team buy in for kotlin on the next project I will revisit this 🙂