[FIXED] How to sort Kotlin ArrayList based on values of another ArrayList?

Issue

I have two ArrayLists:

data class Food(val name: String)

val addedFoodList = arrayListOf(
    Food(name = "Avocado Oil")
)

val foodList = arrayListOf(
    Food(name = "Avocado"),
    Food(name = "Avocado Second"),
    Food(name = "Avocado Third"),
    Food(name = "Avocado Oil"),
)

I want to sort foodList according to the following condition:
If a food with the same name is found in addedFoodList, move this food to the first place in ArrayList

My sorting method:

fun getSortedFoodList(foodList: ArrayList<Food>): List<Food> {
    val sortedFoodList = foodList.sortedBy { food ->
        val foundFood = mockAddedFood.find { addedFood -> 
             food.name == addedFood.name
        }
        
        val indexOf = mockAddedFood.indexOf(foundFood)
        
        return@sortedBy indexOf
    }
    
    return sortedFoodList
}

Result:

[Food(name=Avocado), Food(name=Avocado Second), Food(name=Avocado Third), Food(name=Avocado Oil)]

Expected:

[Food(name=Avocado Oil), Food(name=Avocado), Food(name=Avocado Second), Food(name=Avocado Third)]

Can you please tell me why foodList is not sorted as expected?

Solution

There is two cases :

Food has not been found

When food is not in mockAddedFood, the indexOf method returns -1.

Food has been found

When food is in mockAddedFood, the indexOf variable value is gonna be the index of the food in the mockAddedFood array.

How sortedBy works

For each element, you are returning an int. this int is the placement of your item in the array. The smaller int will be placed at first place.

So in your code, when the food cannot be found, you are returning -1 and that will be always smaller than when you are finding one !

Quick fix

fun getSortedFoodList(foodList: ArrayList<Food>): List<Food> {
    val sortedFoodList = foodList.sortedBy { food ->
        val isIn = addedFoodList.any { addedFood -> 
             food.name == addedFood.name
        }
        
        
        return@sortedBy if(isIn) -1 else 0
    }
    
    return sortedFoodList
}

This code place the food that you found in addedFoodList before the one that you couldn’t found.

Output

[Food(name=Avocado Oil), Food(name=Avocado), Food(name=Avocado Second), Food(name=Avocado Third)]

Answered By – Dinamots

Answer Checked By – Marie Seifert (Easybugfix Admin)

Leave a Reply

(*) Required, Your email will not be published