0

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?

1
  • For reference, note that the function can be written simply as a one-liner: fun getSortedFoodList(foodList: List<Food>) = foodList.partition{ it in addedFoodList }.let{ it.first + it.second }. (Though in either case, you'd get better performance from passing in a set rather than a list.) Commented Aug 15, 2022 at 20:45

1 Answer 1

2

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)]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.