使用谓词映射集合
Mapping over a collection with a predicate
我想 map
使用谓词这样的集合:
- 如果谓词为假,映射应该停止
- 生成的集合必须包含谓词为假的元素
- 谓词为假后不应发生其他映射。
有Sequence.takeWhile满足1和3但不满足2
takeWhile
的例子:
val seq = listOf(1, 2, 3, 4).asSequence()
seq.map { println("mapping: $it"); it }
.takeWhile { it < 3 }
.also { println(it.toList()) } }
输出为
mapping: 1
mapping: 2
mapping: 3
[1, 2]
我需要的结果是 [1, 2, 3]
我不认为标准库中有这样的东西。如果你想坚持使用标准库函数,你很可能需要迭代序列两次。
这是您自己可以轻松实现的东西:
fun <T> Sequence<T>.inclusivelyTakeWhile(predicate: (T) -> Boolean) = sequence {
for (t in this@inclusivelyTakeWhile) {
yield(t)
if (!predicate(t)) {
break
}
}
}
然后做:
seq.map { println("mapping: $it"); it }
. inclusivelyTakeWhile { it < 3 }
.also { println(it.toList()) }
产生了想要的结果。
与standard library's implementation of TakeWhileSequence
相比,此处使用sequence
函数可能会增加一些开销。如果您关心这一点,您可以创建 TakeWhileSequence
和 return 的修改版本。
我想 map
使用谓词这样的集合:
- 如果谓词为假,映射应该停止
- 生成的集合必须包含谓词为假的元素
- 谓词为假后不应发生其他映射。
有Sequence.takeWhile满足1和3但不满足2
takeWhile
的例子:
val seq = listOf(1, 2, 3, 4).asSequence()
seq.map { println("mapping: $it"); it }
.takeWhile { it < 3 }
.also { println(it.toList()) } }
输出为
mapping: 1
mapping: 2
mapping: 3
[1, 2]
我需要的结果是 [1, 2, 3]
我不认为标准库中有这样的东西。如果你想坚持使用标准库函数,你很可能需要迭代序列两次。
这是您自己可以轻松实现的东西:
fun <T> Sequence<T>.inclusivelyTakeWhile(predicate: (T) -> Boolean) = sequence {
for (t in this@inclusivelyTakeWhile) {
yield(t)
if (!predicate(t)) {
break
}
}
}
然后做:
seq.map { println("mapping: $it"); it }
. inclusivelyTakeWhile { it < 3 }
.also { println(it.toList()) }
产生了想要的结果。
与standard library's implementation of TakeWhileSequence
相比,此处使用sequence
函数可能会增加一些开销。如果您关心这一点,您可以创建 TakeWhileSequence
和 return 的修改版本。