Home > other >  get every other index in for loop
get every other index in for loop

Time:04-20

I have an interesting issue. I have a string that's in html and I need to parse a table so that I can get the data I need out of that table and present it in a way that looks good on a mobile device. So I use regex and it works just fine but now I'm porting my code to using Kotlin and the solution I have is not porting over well. Here is what the solution looks currently:

var pointsParsing = Regex.Matches(htmlBody, "<td.*?>(.*?)</td>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
var pointsSb = new StringBuilder();

for (var i = 0; i < pointsParsing.Count; i = 2)
{
    var pointsTitle = pointsParsing[i].Groups[1].Value.Replace("&amp;", "&");
    var pointsValue = pointsParsing[i 1].Groups[1].Value;

    pointsSb.Append($"{pointsTitle} {pointsValue} {pointsVerbiage}\n");
}

return pointsSb.ToString();

as you see, each run in the loop I get two results from the regex search and as a result I tell the for loop to increment by two to avoid collision.

However I don't seem to have this ability within Kotlin, I know how to get the index in a for loop but no idea on how to tell it to skip by 2 so I don't accidentally get something I already parsed on the last loop lap.

how would I tell the for loop to work the way I need it to in Kotlin?

CodePudding user response:

You might be looking for chunked which lets you split an iterable into chunks of e.g. 2 elements:

ptsListResults.chunked(2).forEach { data -> // data is a list of (up to) two elements
    val pointsTitle = data[0].groups[1]!!.value
    val pointsValue = data[1].groups[1]!!.value
    // etc
}

so that's more explicit about breaking your list up into meaningful chunks, and operating within the structure of those chunks, rather that manipulating indices.

There's also windowed which is a bit more complex and gives you more options, one of which is disallowing partial windows (i.e. chunks at the end that don't have the required number of elements). Probably doesn't apply here but just so's you know!

CodePudding user response:

I found a solution that looks to work and thought I'd share.

thanks to this SO answer I see how you can skip over the indexes.

val pointsListSearch = "<td.*?>(.*?)</td>".toRegex()
val pointsListSearchResults = pointsListSearch.findAll(htmlBody)
val pointsSb = StringBuilder()

val ptsListResults = pointsListSearchResults.toList()

for (i in ptsListResults.indices step 2)
{
    val pointsTitle = ptsListResults[i].groups[1]!!.value
    val pointsValue = ptsListResults[i 1].groups[1]!!.value

    pointsSb.append("${pointsTitle}: ${pointsValue}")
}
  • Related