【问题标题】:Kotlin. Get distinct values from collection科特林。从集合中获取不同的值
【发布时间】:2022-09-26 11:17:33
【问题描述】:

数据看起来像这样

    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)
}
  • 为什么要使用列表列表,每个列表似乎都有一些隐式结构,而不是一些合适对象的列表?
  • 实际上数据来自 JSON 格式的 Web 服务器,并且包含 JSON 数组和对象。我将其转换为我的课程。该列表只是我的问题。

标签: kotlin collections distinct


【解决方案1】:

以下应该按预期工作:

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 类,而不是如下:

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)
}

如果您想要/需要保留嵌套列表,另一种可能性如下(感谢@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)
}

【讨论】:

  • 您能否将when 块简化​​为(it as? Person)?.name 之类的东西?
  • 这实际上更简单;)感谢您的提示!我会更新我的答案。
  • 最后一张很酷。
  • 你的问题现在解决了吗?如果是,我的回答帮助您考虑支持它,甚至接受它作为答案,以便它可以“关闭”并且其他人可以从中受益并轻松理解这可能是类似问题的可能解决方案;)谢谢!
【解决方案2】:

另一种选择是创建一个自定义类来表示您的内部列表。

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)

【讨论】:

    【解决方案3】:
    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 名称 = arr.map { listOf(it.person1.name, it.person2.name) }.distinct() println(名字)

    【讨论】:

      猜你喜欢
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-11
      • 2023-02-14
      • 2021-12-23
      • 2023-03-31
      相关资源
      最近更新 更多