Home > Net >  Convert String into list of Pairs: Kotlin
Convert String into list of Pairs: Kotlin

Time:01-18

Is there an easier approach to convert an Intellij IDEA environment variable into a list of Tuples?

My environment variable for Intellij is

GROCERY_LIST=[("egg", "dairy"),("chicken", "meat"),("apple", "fruit")]

The environment variable gets accessed into Kotlin file as String.

val g_list = System.getenv("GROCERY_LIST")

Ideally I'd like to iterate over g_list, first element being ("egg", "dairy") and so on. And then ("egg", "dairy") is a tuple/pair

I have tried to split g_list by comma that's NOT inside quotes i.e

val splitted_list = g_list.split(",(?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*\$)".toRegex()).toTypedArray()

this gives me first element as [("egg", second element as "dairy")] and so on.

Also created a data class and tried to map the string into data class using jacksonObjectMapper following this link:

val mapper = jacksonObjectMapper()
val g_list = System.getenv("GROCERY_LIST")
val myList: List<Shopping> = mapper.readValue(g_list)

data class Shopping(val a: String, val b: String)

CodePudding user response:

Never a good idea to use regex to match parenthesis.

I would suggest a step-by-step approach:

You could first match the name and the value by

(\w )=(.*)

There you get the name in group 1 and the value in group 2 without caring about any subsequent = characters that might appear in the value.

If you then want to split the value, I would get rid of start and end parenthesis first by matching by

(?<=\[\().*(?=\)\])

(or simply cut off the first and last two characters of the string, if it is always given it starts with [( and ends in )])

Then get the single list entries from splitting by

\),\(

(take care that the split operation also takes a regex, so you have to escape it)

And for each list entry you could split that simply by

,\s*

or, if you want the quote character to be removed, use a match with

\"(.*)\",\s*\"(.*)\"

where group 1 contains the key (left of equals sign) and group 2 the value (right of equals sign)

CodePudding user response:

  1. You can create a regular expression to match all strings in your environmental variable. Regex::findAll()
  2. Then loop through the strings while creating a list of Shopping objects.
// Raw data set.
val groceryList: String = "[(\"egg\", \"dairy\"),(\"chicken\", \"meat\"),(\"apple\", \"fruit\")]"

// Build regular expression.
val regex = Regex("\"([\\s\\S] ?)\"")
val matchResult = regex.findAll(groceryList)
val iterator = matchResult.iterator()

// Create a List of `Shopping` objects.
var first: String = "";
var second: String = "";
val shoppingList = mutableListOf<Shopping>()
var i = 0;

while (iterator.hasNext()) {
    val value = iterator.next().value;

    if (i % 2 == 0) {
        first = value;
    } else {
        second = value;
        shoppingList.add(Shopping(first, second))
        first = ""
        second = ""
    }

    i  

}

// Print Shopping List.
for (s in shoppingList) {
    println(s)
}

// Output.
/*
    Shopping(a="egg", b="dairy")
    Shopping(a="chicken", b="meat")
    Shopping(a="apple", b="fruit")
*/

data class Shopping(val a: String, val b: String)
  • Related