Last active
December 5, 2020 05:19
-
-
Save Kalaiz/c05749912dfbe5c554f9b99f7677eebc to your computer and use it in GitHub Desktop.
Split Kotlin List<String> using Delimiter Testing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* https://stackoverflow.com/questions/65140871/split-list-when-predicate-is-true*/ | |
/* First Way */ | |
inline fun List<String>.splitWhenOne(predicate: (String)->Boolean):List<List<String>> { | |
val list = mutableListOf<MutableList<String>>() | |
var needNewList = false | |
forEach { | |
string-> | |
if(!predicate(string)){ | |
if(needNewList||list.isEmpty()){ | |
list.add(mutableListOf(string)) | |
needNewList= false | |
} | |
else { | |
list.last().add(string) | |
} | |
} | |
else { | |
/* When a delimiter is found */ | |
needNewList = true | |
} | |
} | |
return list | |
} | |
/* Second Way */ | |
inline fun List<String>.splitWhenTwo(predicate: (String)->Boolean):List<List<String>> { | |
val list = mutableListOf<List<String>>() | |
withIndex() | |
.filter { indexedValue -> predicate(indexedValue.value) || indexedValue.index==0 || indexedValue.index==size-1} // Just getting the delimiters with their index; Include 0 and last -- so to not ignore it while pairing later on | |
.zipWithNext() // zip the IndexValue with the adjacent one so to later remove continuous delimiters; Example: Indices : 0,1,2,5,7 -> (0,1),(1,2),(2,5),(5,7) | |
.filter { pair-> pair.first.index + 1 != pair.second.index } // Getting rid of continuous delimiters; Example: (".",".") will be removed, where "." is the delimiter | |
.forEach{pair-> | |
val startIndex = if(predicate(pair.first.value)) pair.first.index+1 else pair.first.index // Trying to not consider delimiters | |
val endIndex = if(!predicate(pair.second.value) && pair.second.index==size-1) pair.second.index+1 else pair.second.index // subList() endIndex is exclusive | |
list.add(subList(startIndex,endIndex)) // Adding the relevant sub-list | |
} | |
return list | |
} | |
/* Third Way */ | |
inline fun List<String>.splitWhenThree(predicate: (String)-> Boolean):List<List<String>> = | |
foldIndexed(mutableListOf<MutableList<String>>(),{index, list, string-> | |
when { | |
predicate(string) -> if(index<size-1 && !predicate(get(index+1))) list.add(mutableListOf()) // Adds a new List within the output List; To prevent continuous delimiters -- !predicate(get(index+1)) | |
list.isNotEmpty() -> list.last().add(string) // Just adding it to lastly added sub-list, as the string is not a delimiter | |
else -> list.add(mutableListOf(string)) // Happens for the first String | |
} | |
list}) | |
fun main(){ | |
val testCase = listOf( | |
"This is", "the", "first sentence", ".", | |
"And", "now there is", "a second", "one", ".", | |
"Nice","." | |
) | |
val testCaseTwo = listOf( | |
".",".","This is", "the", "first sentence", ".", | |
"And", "now there is", "a second", "one", ".", | |
"Nice",".",".",".",".",".","." | |
) | |
val testCaseThree = listOf( | |
"|",".","This is", "the", "first sentence", ".", | |
"And", "now there is", "a second", "one", "|", | |
"this"," the third","|", | |
"this","/","the","last" | |
) | |
/* | |
* The following two tests should yield the result | |
* listOf( | |
* listOf("This is", "the", "first sentence"), | |
* listOf("And", "now there is", "a second", "one"), | |
* listOf("Nice") | |
* ) | |
*/ | |
println("Test Case One") | |
testAll(testCase,".") | |
println() | |
println("Test Case Two") | |
testAll(testCaseTwo,".") | |
/* | |
* The following test should be the result of the transformation | |
* listOf( | |
* listOf(".",This is", "the", "first sentence","." ."And", "now there is", "a second", "one"), | |
* listOf("this","the third"), | |
* listOf("this","/","the","last") | |
* ) | |
*/ | |
println() | |
println("Test Case Three") | |
testAll(testCaseThree,"|") // Note Delimiter is "|" | |
} | |
fun testAll(list:List<String>,delimiter:String){ | |
println( list.splitWhenOne {it==delimiter } ) | |
println( list.splitWhenTwo {it==delimiter } ) | |
println( list.splitWhenThree {it==delimiter } ) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment