科特林。从集合中获取不同的值
Kotlin. Get distinct values from collection
数据看起来像这样
class Person (
var id:Int,
var name:String
)
class Option (
var level:Int
)
val p1 = Person(1, "A")
val p2 = Person(2, "B")
val opt1 = Option((0..1000).random())
val opt2 = Option((0..1000).random())
val opt3 = Option((0..1000).random())
val opt4 = Option((0..1000).random())
val arr = listOf(
listOf(p1,p2,opt1),
listOf(p1,p2,opt2),
listOf(p1,p2,opt3),
listOf(p2,p1,opt4)
)
我想获得“A”和“B”作为名称的唯一值。
如果集合看起来像这样就很容易了:
val simple = listOf(p1,p2,p2,p1).distinctBy{it.name}
simple.forEach {
println(it.name)
}
以下应按预期工作:
fun main() {
val p1 = Person(1, "A")
val p2 = Person(2, "B")
val opt1 = Option((0..1000).random())
val opt2 = Option((0..1000).random())
val opt3 = Option((0..1000).random())
val opt4 = Option((0..1000).random())
val arr = listOf(
listOf(p1,p2,opt1),
listOf(p1,p2,opt2),
listOf(p1,p2,opt3),
listOf(p2,p1,opt4)
)
val distinctNames = arr.flatten().mapNotNull {
when(it) {
is Person -> it.name
else -> null
}
}.distinct()
println(distinctNames)
}
class Person (
var id:Int,
var name:String
)
class Option (
var level:Int
)
但是,我建议您尽可能替换嵌套列表,这样您就可以在映射时避免 when
块。如果可能的话,我会建议 Triple
class 如下:
fun main() {
val p1 = Person(1, "A")
val p2 = Person(2, "B")
val opt1 = Option((0..1000).random())
val opt2 = Option((0..1000).random())
val opt3 = Option((0..1000).random())
val opt4 = Option((0..1000).random())
val arr = listOf(
Triple(p1,p2,opt1),
Triple(p1,p2,opt2),
Triple(p1,p2,opt3),
Triple(p2,p1,opt4)
)
val distinctNames = arr.flatMap { listOf(it.first.name, it.second.name) }
.distinct()
println(distinctNames)
}
如果您 want/need 保留嵌套列表,另一种可能性如下(感谢@gidds 的提示):
fun main() {
val p1 = Person(1, "A")
val p2 = Person(2, "B")
val opt1 = Option((0..1000).random())
val opt2 = Option((0..1000).random())
val opt3 = Option((0..1000).random())
val opt4 = Option((0..1000).random())
val arr = listOf(
listOf(p1,p2,opt1),
listOf(p1,p2,opt2),
listOf(p1,p2,opt3),
listOf(p2,p1,opt4)
)
val distinctNames = arr.flatten().mapNotNull { (it as? Person)?.name }
.distinct()
println(distinctNames)
}
另一种选择是创建自定义 class 来代表您的内部列表。
class PersonOption(
val person1: Person,
val person2: Person,
val option: Option
)
val arr = listOf(
PersonOption(p1, p2, opt1),
PersonOption(p1, p2, opt2),
PersonOption(p1, p2, opt3),
PersonOption(p2, p1, opt4)
)
val names = arr.flatMap { listOf(it.person1.name, it.person2.name) }.distinct()
println(names)
数据看起来像这样
class Person (
var id:Int,
var name:String
)
class Option (
var level:Int
)
val p1 = Person(1, "A")
val p2 = Person(2, "B")
val opt1 = Option((0..1000).random())
val opt2 = Option((0..1000).random())
val opt3 = Option((0..1000).random())
val opt4 = Option((0..1000).random())
val arr = listOf(
listOf(p1,p2,opt1),
listOf(p1,p2,opt2),
listOf(p1,p2,opt3),
listOf(p2,p1,opt4)
)
我想获得“A”和“B”作为名称的唯一值。
如果集合看起来像这样就很容易了:
val simple = listOf(p1,p2,p2,p1).distinctBy{it.name}
simple.forEach {
println(it.name)
}
以下应按预期工作:
fun main() {
val p1 = Person(1, "A")
val p2 = Person(2, "B")
val opt1 = Option((0..1000).random())
val opt2 = Option((0..1000).random())
val opt3 = Option((0..1000).random())
val opt4 = Option((0..1000).random())
val arr = listOf(
listOf(p1,p2,opt1),
listOf(p1,p2,opt2),
listOf(p1,p2,opt3),
listOf(p2,p1,opt4)
)
val distinctNames = arr.flatten().mapNotNull {
when(it) {
is Person -> it.name
else -> null
}
}.distinct()
println(distinctNames)
}
class Person (
var id:Int,
var name:String
)
class Option (
var level:Int
)
但是,我建议您尽可能替换嵌套列表,这样您就可以在映射时避免 when
块。如果可能的话,我会建议 Triple
class 如下:
fun main() {
val p1 = Person(1, "A")
val p2 = Person(2, "B")
val opt1 = Option((0..1000).random())
val opt2 = Option((0..1000).random())
val opt3 = Option((0..1000).random())
val opt4 = Option((0..1000).random())
val arr = listOf(
Triple(p1,p2,opt1),
Triple(p1,p2,opt2),
Triple(p1,p2,opt3),
Triple(p2,p1,opt4)
)
val distinctNames = arr.flatMap { listOf(it.first.name, it.second.name) }
.distinct()
println(distinctNames)
}
如果您 want/need 保留嵌套列表,另一种可能性如下(感谢@gidds 的提示):
fun main() {
val p1 = Person(1, "A")
val p2 = Person(2, "B")
val opt1 = Option((0..1000).random())
val opt2 = Option((0..1000).random())
val opt3 = Option((0..1000).random())
val opt4 = Option((0..1000).random())
val arr = listOf(
listOf(p1,p2,opt1),
listOf(p1,p2,opt2),
listOf(p1,p2,opt3),
listOf(p2,p1,opt4)
)
val distinctNames = arr.flatten().mapNotNull { (it as? Person)?.name }
.distinct()
println(distinctNames)
}
另一种选择是创建自定义 class 来代表您的内部列表。
class PersonOption(
val person1: Person,
val person2: Person,
val option: Option
)
val arr = listOf(
PersonOption(p1, p2, opt1),
PersonOption(p1, p2, opt2),
PersonOption(p1, p2, opt3),
PersonOption(p2, p1, opt4)
)
val names = arr.flatMap { listOf(it.person1.name, it.person2.name) }.distinct()
println(names)