5

I rather have this ugly way of building a string from a list as:

val input = listOf("[A,B]", "[C,D]")

val builder = StringBuilder()
builder.append("Serialized('IDs((")
for (pt in input) {
 builder.append(pt[0] + " " + pt[1])
 builder.append(", ")  
}
builder.append("))')")

The problem is that it adds a comma after the last element and if I want to avoid that I need to add another if check in the loop for the last element.

I wonder if there is a more concise way of doing this in kotlin?

EDIT

End result should be something like:

Serialized('IDs((A B,C D))')
2
  • 2
    How should the end result look? Commented Feb 16, 2022 at 8:57
  • Added what the end result shoudl look like Commented Feb 16, 2022 at 9:36

3 Answers 3

5

In Kotlin you can use joinToString for this kind of use case (it deals with inserting the separator only between elements).

It is very versatile because it allows to specify a transform function for each element (in addition to the more classic separator, prefix, postfix). This makes it equivalent to mapping all elements to strings and then joining them together, but in one single call.

If input really is a List<List<String>> like you mention in the title and you assume in your loop, you can use:

input.joinToString(
    prefix = "Serialized('IDs((",
    postfix = "))')",
    separator = ", ",
) { (x, y) -> "$x $y" }

Note that the syntax with (x, y) is a destructuring syntax that automatically gets the first and second element of the lists inside your list (parentheses are important).

If your input is in fact a List<String> as in listOf("[A,B]", "[C,D]") that you wrote at the top of your code, you can instead use:

input.joinToString(
    prefix = "Serialized('IDs((",
    postfix = "))')",
    separator = ", ",
) { it.removeSurrounding("[", "]").replace(",", " ") }
Sign up to request clarification or add additional context in comments.

4 Comments

Does this even compile? I have tried on Kotlin 1.6.10, this transformer has mismatching components.
This code would work if the input was a List of Lists, like: listOf(listOf("A","B"), listOf("C","D")), but it does not compile with the OPs input string.
The OP was mentioning list of lists in the title, and the body of the OP's loop was suggesting the same, so I didn't pay attention to the input line. This works for a List<List<String>>. I added an alternative for the actual OP's input line
Aah.. right, missed the list of list part.
1
val input = listOf("[A,B]", "[C,D]")

val result =
  "Serialized('IDs((" +
  input.joinToString(",") {  it.removeSurrounding("[", "]").replace(",", " ") } +
  "))')"

println(result)   // Output:   Serialized('IDs((A B,C D))')

Comments

1

Kotlin provides an extension function [joinToString][1] (in Iterable) for this type of purpose.

input.joinToString(",", "Serialized('IDs((", "))')")

This will correctly add the separator.

2 Comments

mmh this doesn't transform the elements like the OP is doing, apart from that, I guess it's just my answer
Has OP mentioned what exact format is looking for?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.