got-stuck let's say I have this code: ```val stri...
# announcements
m
got-stuck let's say I have this code:
Copy code
val string = "<p></p>this<p></p>"
        
val arrs = listOf("<p data-id=\"1\"></p>", "<p data-id=\"2\"></p>")

var replacedString = ""

arrs.forEach {
    val pTag = "<p></p>"

    replacedString = string.replace(pTag, it)

}

println(replacedString)
It should show
<p data-id="1"></p>this<p data-id="2"></p>
, but it shows
<p data-id="2"></p>this<p data-id="2"></p>
instead
n
that's likely going to require an HTML parser
also you have an attribute on a closing tag in your example
m
yea. I've considered it
I've edited my post. got typo
but I got stuck on the logic
n
you could just do
"<p data-id=\"${arrs.first()}\"></p>this<p data-id=\"${arrs.last()}\"></p>"
m
the problem is the transformed string and the
listOf
would be dynamic so if I have:
Copy code
val arrs = listOf("1", "2", "3")
the transformed string would look:
<p data-id="1"></p>this<p data-id="2"></p><p data-id="3"></p>
or
<p data-id="1"></p>this<p data-id="2"></p>that<p data-id="3"></p>
so on and so forth
n
so...really it's just interleaving two things, yeah?
m
yes
Copy code
var replacedString = ""

        arrs.forEach {
            val pTag = "<p></p>"

            replacedString = string.replace(pTag, it)

        }
        
        println(replacedString)
this doesn't work it always gets the last index so the
data-id
value is
3
n
maybe you can do something like this.
zip
only produces a collection as long as the shorter one though.
m
why is there
letters
variable?
n
you have a list of ids and a list of whatever "this" and "that" is
m
what is the reason of having
letters
variable?
because I see that code gets out of context of my problem thank you anyway
I've edited my post to get the better picture out of it
p
the issue is
replacedString = string.replace(…)
. you’re overwriting the
replacedString
var on each iteration, and reading from the original
string
☝🏻 1
d
It looks like you want to replace the <p></p> from the original string with whatever the arrs are and then if there are extra arrs you want to just append them to the end. How about
Copy code
val values = string.split(pTag)
arrs.zip(values + List(arrs.length - values.length) { “” }) { a,b -> listOf(a,b) }.flatten().joinToString(“”)
So essentially remove all the ptags and produce a list of this (and that), and then pad that list with empty strings so that it’s the same length as the list of arrs. Then zip the two lists together finally joining them all into a single string.
In the case your arrs is just 1, 2, 3 you could add a map before the zip.
arrs.map { “<p data-id=\”$it\”></p>” }.zip...
Allowing you to create your p tag with data id from the number values before zipping them in place
If your list of arrs might be shorter than the list of your strings then you’d need to add additional logic of course. But yeah, replace won’t work because replace will replace all instances of the pTag, and the replacedString will be overwritten every time until the final time resulting in just the last arr showing up
p
i guess in my opinion, this solution in itself is not usually a good idea. either pick an existing templating engine or hard-code your cases instead of using two separate things (the string and the array) that you need to manually keep in synch. this is unlikely to be a safe solution that is easy to maintain going forward. without more context on how you’re going to use it, it’s hard to give good advice about what would be a good alternate solution.
👆 2
d
Absolutely. Depends what the use case is as to what the best solution is. But from the perspective of wanting to replace some string with an element from some list one by one and then tuck the remaining elements of the list at the end I think it’s a viable approach. Whether it’s good for the intended use depends.
n
Many useful insights here. But just to provide the answer to the initial question: your code does not work because 1. you modify
string
instead of
replacedString
in your loop iterations. Thus, every iteration starts with the same data and overwrites whatever the previous iteration did 2.
String::replace
replaces all matches in the String and not just the first one. Thus, your 2nd (and final) iteration does
replacedString = "<p></p>this<p></p>".replace("<p></p>", "<p data-id=\"2\"></p>")
and you end up with the result you see. Minimal changes to your code to provide the desired output:
Copy code
var replacedString = string

arrs.forEach {
   	val pTag = "<p></p>"
   	replacedString = replacedString.replaceFirst(pTag, it)
}
1
m