mdNJ
mdNJ

Reputation: 1

how can i sort 2D mutableListof<Any> by the first element in Kotlin

how can i sort 2D mutable list of array by the first element of array?

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

i want to get sort this mutablelist by alphabetical order of the first element of each list.

output should be

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

Upvotes: 0

Views: 146

Answers (3)

cactustictacs
cactustictacs

Reputation: 19592

You've got two problems here:

  • your list contains elements of Any, which doesn't imply any kind of "first element"
  • you can only compare things which implement Comparable (unless you pass in your own comparator, or do your own comparison logic in the sorting function)

First, if this list really is supposed to hold "lists of elements", then you should make that part of the type. We can use the general Collection type (or Iterable which it extends):

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

Unfortunately that doesn't work for arrays, which are their own thing. If you want to be able to mix and match, you need to keep the MutableList<Any> type, and do some type checking in the sort function:

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

That example demonstrates your second problem too - how to sort a bunch of Anys. Since you said you want them alphabetically sorted (and without knowing what you're going to put in there besides strings and numbers) one approach is to just call toString() on everything.

That's one of the few methods Any has, so if you can't be more specific about the types in your "lists", you can at least sort on that. Whether it'll be any use out-of-the-box depends on the objects you put in there!

Upvotes: 0

Otto Kaaij
Otto Kaaij

Reputation: 1

This is difficult, because you have very limited type information.

If you the elements of the inner lists always have three values of type String, String, Integer, you should probably use a triple:

val books = mutableListOf<Triple<String, String, Int>>(
    Triple("abc","b",1),
    Triple("abb","y",2),
        Triple("abcl","i",3)
)

books.sortBy { t -> t.first }

If the inner lists are always lists, but with different lengths and types, but it is known that the are always strings you can do something like

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

books.sortBy { t -> t.first() as String }

If you don't know any type information, and books is truly a MutableList<Any>, then you cannot compare: you don't what you are comparing.

Upvotes: 0

Ivo
Ivo

Reputation: 23312

You can do

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

Upvotes: 0

Related Questions