【问题标题】:how can i sort 2D mutableListof<Any> by the first element in Kotlin如何按 Kotlin 中的第一个元素对 2D mutableListof<Any> 进行排序
【发布时间】:2022-11-11 23:58:38
【问题描述】:

如何按数组的第一个元素对二维可变数组列表进行排序?

val books = mutableListOf<Any>(
  listof("abc","b",1),
  listof("abb","y",2),
  listof("abcl"."i",3)
)

我想按每个列表的第一个元素的字母顺序对这个可变列表进行排序。

输出应该是

[listof("abb","y",2), listof("abc","b",1), listof("abcl"."i",3) ]

【问题讨论】:

  • 只是一个评论,因为它与您的特定问题无关,但如果您在任何实际代码中使用 List&lt;Any&gt; 应该是非常罕见的。 Kotlin 是一种强类型语言,因此您可以创建一个类来表示具有类型安全性的数据组。

标签: kotlin sorting mutablelist


【解决方案1】:

你可以做

books.sortBy { (it as List<*>).first() as String }

【讨论】:

    【解决方案2】:

    这很困难,因为您的类型信息非常有限。

    如果内部列表的元素始终具有 String、String、Integer 类型的三个值,则可能应该使用三元组:

    val books = mutableListOf<Triple<String, String, Int>>(
        Triple("abc","b",1),
        Triple("abb","y",2),
            Triple("abcl","i",3)
    )
    
    books.sortBy { t -> t.first }
    

    如果内部列表始终是列表,但具有不同的长度和类型,但众所周知,它们总是字符串你可以做类似的事情

    val books = mutableListOf<List<Any>>(
        listOf("abc","b",1),
        listOf("abb","y",2),
        listOf("abcl","i",3)
    )
    
    books.sortBy { t -> t.first() as String }
    

    如果您不知道任何类型信息,并且书籍确实是MutableList&lt;Any&gt;,那么您无法比较:您不知道您在比较什么。

    【讨论】:

    • @ivo 的答案适用于此示例,但是当书籍的元素不是列表或列表的第一个元素不是字符串时会中断(就像我的答案一样)。
    【解决方案3】:

    你这里有两个问题:

    • 您的列表包含Any 的元素,这并不意味着任何类型的“第一个元素”
    • 你只能比较实现Comparable的东西(除非你传入你自己的比较器,或者在排序函数中做你自己的比较逻辑)

    首先,如果这个列表真的应该包含“元素列表”,那么你应该把它作为类型的一部分。我们可以使用通用的Collection 类型(或它扩展的Iterable):

    val books = mutableListOf<Collection<Any>>(
      listof("abc","b",1),
      ...
    

    不幸的是,这不适用于数组,这是他们自己的事情。如果希望能够混搭,则需要保留MutableList&lt;Any&gt;类型,并在sort函数中做一些类型检查:

    // all kinds of things going in here
    val books = mutableListOf<Any>(
      listOf("abc","b",1),
      arrayOf("abb","y",2),
      setOf("abcl","i",3)
    )
    
    books.sortedBy {
       when(it) {
          is Collection<*> -> it.first().toString()
          is Array<*> -> it.first().toString()
          // or your fallback could just be it.toString()
          else -> throw Exception("can't compare this thing")
       }
    }
    

    该示例也演示了您的第二个问题 - 如何对一堆Anys 进行排序。既然您说您希望它们按字母顺序排序(并且不知道除了字符串和数字之外您将在其中放入什么),一种方法是在所有内容上调用toString()

    这是Any 拥有的少数功能之一,因此如果您不能更具体地了解“列表”中的类型,您至少可以对其进行排序。开箱即用是否有任何用途取决于您放入其中的对象!

    【讨论】:

      猜你喜欢
      • 2013-12-27
      • 1970-01-01
      • 2022-02-12
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      • 2020-05-24
      • 1970-01-01
      相关资源
      最近更新 更多