Mark
04/21/2022, 4:21 AMIterable
and returns true if and only if all items return the same value for a given lambda? I don't care what the value is. I know I can just apply lambda to first item and then use Iterable.all {}
but I was wondering if there was a nicer way.Maroš Šeleng
04/21/2022, 6:09 AMyourList.distinctBy { getResult(it) }.size == 1
Mark
04/21/2022, 6:11 AMMaroš Šeleng
04/21/2022, 6:33 AMMark
04/21/2022, 6:35 AMMichael de Kaste
04/21/2022, 7:37 AMyourList.asSequence().map{ applyLambda(it) }.zipWithNext().any{ (a,b) -> a != b }
if the first element equals the second element, you might as well compare with the second element as well when you are at the third element, etc.Mark
04/21/2022, 7:43 AMfun <T> Iterable<T>.allSameBy(
transform: (T) -> Any,
): Boolean = asSequence()
.map(transform)
.zipWithNext()
.all { (a, b) -> a == b }
ephemient
04/22/2022, 11:15 AMfun <T> Iterable<T>.allSameBy(
transform: (T) -> Any,
): Boolean {
val i = iterator()
if (!i.hasNext()) return true
val expected = transform(i.next())
for (item in iterator) if (transform(item) != expected) return false
return true
}
Mark
04/22/2022, 1:33 PMall
) does a similar check
fun <T> Iterable<T>.allSameBy(transform: (T) -> Any): Boolean {
if (this is Collection && size < 2) return true
return asSequence()
.map(transform)
.zipWithNext()
.all { (a, b) -> a == b }
}
fun <T> Iterable<T>.allSameBy(
transform: (T) -> Any,
): Boolean {
val expected = transform(firstOrNull() ?: return true)
return all { transform(it) == expected }
}
ephemient
04/22/2022, 1:42 PMCopyOnWriteArrayList
is consistent if you iterate it once, but if you're looking at first and all separately, they may not be consistent under mutationMark
04/22/2022, 1:45 PMfun <T> Iterable<T>.allSameBy(
transform: (T) -> Any,
): Boolean {
var expected: Any? = null
return all {
if (expected == null) {
expected = transform(it)
return@all true
}
transform(it) == expected
}
}
ephemient
04/22/2022, 1:48 PMMark
04/22/2022, 1:48 PMlateinit
?ephemient
04/22/2022, 1:49 PMMark
04/22/2022, 1:49 PMAny
doesn't that mean it can't return null?ephemient
04/22/2022, 1:50 PMMark
04/22/2022, 1:53 PMephemient
04/22/2022, 1:53 PMMark
04/22/2022, 1:55 PMfun <T> Iterable<T>.allSameBy(transform: (T) -> Any): Boolean {
// let's see if we can avoid creating the sequence
if (this is Collection && size < 2) return true
// return true iff 0 or 1 distinct transformed values
// however, don't use count() because that will force iteration over entire iterable
return this.asSequence().map(transform).distinct().drop(1).none()
}
ephemient
06/04/2022, 9:53 AMgroupingBy
which creates an intermediate data structure). so I would not use Sequence
as long as there's a better way. but your code, your preferences…Mark
06/04/2022, 1:35 PMinline fun <T> Iterable<T>.allSameBy(transform: (T) -> Any): Boolean {
// let's see if we can avoid creating the iterator
if (this is Collection && this.size < 2) {
return true
}
val iterator = this.iterator()
if (!iterator.hasNext()) {
return true
}
val firstItemTransformed = transform(iterator.next())
if (!iterator.hasNext()) {
return true
}
for (item in iterator) if (transform(item) != firstItemTransformed) return false
return true
}
Pretty much what you wrote a month ago but with some extra checks