Skip to content

Commit 3d00298

Browse files
Add List<E>.split(predicate) and List<E>.indexOf(predicate)
1 parent 8a2658b commit 3d00298

1 file changed

Lines changed: 38 additions & 10 deletions

File tree

src/main/kotlin/KotlinFunctionLibrary.kt

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,16 +1038,44 @@ println("workingList2=$workingList2")*/
10381038
)
10391039
}
10401040
}
1041-
/**
1042-
* Determines whether [this] list contains a sublist such that at least one element in each list of said sublist is contained in a parallel sublist of [other].
1043-
* This is a direct adaptation of [CharSequence.contains(CharSequence)].
1044-
* For example the following returns true:
1045-
val x = listOf( listOf('a', 'b', 'c'), listOf('d', 'e', 'f') )
1046-
val y = listOf(listOf('x' ,'y' ,'z'), listOf('1', '2', 'a'), listOf('3', 'f', '4'), listOf('9'))
1047-
val z = listOf( listOf('1', '2', 'a'), listOf('3', 'f', '4') )
1048-
println(x in y) //prints true
1049-
println(x in z) //prints true
1050-
*/
1041+
1042+
/**
1043+
* Returns index of the first element after [offset] matching the given [predicate], or -1 if the list does not contain such element.
1044+
*/
1045+
public inline fun <T> List<T>.indexOf(predicate: (T) -> Boolean, offset: Int): Int {
1046+
var index = 0
1047+
for (item in this.subList(offset, this.size)) {
1048+
if (predicate(item))
1049+
return index
1050+
index++
1051+
}
1052+
return -1
1053+
}
1054+
1055+
/**
1056+
* Splits a list by a predicate. List analog to [String.split]
1057+
* */
1058+
fun <E> List<E>.split(includeDelimiter: Boolean = false, predicate: (E) -> Boolean): List<List<E>> {
1059+
return flatMapIndexed { index, element ->
1060+
when {
1061+
index == 0 || index == lastIndex -> listOf(index)
1062+
predicate(element) -> listOf(index - 1, index + 1)
1063+
else -> emptyList()
1064+
}
1065+
}
1066+
.windowed(size = 2, step = 2) { (from, to) -> slice( (if(includeDelimiter) (from - 1).coerceAtLeast(0) else from)..to) }
1067+
}
1068+
1069+
/**
1070+
* Determines whether [this] list contains a sublist such that at least one element in each list of said sublist is contained in a parallel sublist of [other].
1071+
* This is a direct adaptation of [CharSequence.contains(CharSequence)].
1072+
* For example the following returns true:
1073+
* val x = listOf( listOf('a', 'b', 'c'), listOf('d', 'e', 'f') )
1074+
* val y = listOf(listOf('x' ,'y' ,'z'), listOf('1', '2', 'a'), listOf('3', 'f', '4'), listOf('9'))
1075+
* val z = listOf( listOf('1', '2', 'a'), listOf('3', 'f', '4') )
1076+
* println(x in y) //prints true
1077+
* println(x in z) //prints true
1078+
*/
10511079
operator fun <T> List<Iterable<T>>.contains(other: List<Iterable<T>>): Boolean = contains(other) { thisList, otherList -> thisList.any { it in otherList } }
10521080

10531081
fun <T> List<T>.contains(other: List<T>, predicate: (thisElement: T, otherElement: T) -> Boolean): Boolean = indexOf(other, 0, this.size, predicate) >= 0

0 commit comments

Comments
 (0)