Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 273 Vote(s) - 3.46 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sorting list based on another list's order

#1
I need to sort a list of `Person` objects(`List<Person>`, where each `Person` object has few attributes like `id`(unique), `name`, `age`… etc).


The sorting order is based on another list. That list contains a set of `Person` `id`'s (A `List<String>` which is already sorted).

What is the best way to order the `List<Person>` in the same order as the list of `id`'s using Kotlin or Java.

Example:

List Person {
(“ID1”,”PERSON1”,22,..), (“ID-2”,”PERSON2”,20,..) ), (“ID-3”,”PERSON3”,19,..),…..
}

Ordered Id List :

List of ID {(“ID2”), (“ID1”),(”ID3”)….}

Sorted `Person` list should be:

List PERSON {
(“ID-2”,”PERSON 2”,20,..) ), (“ID1”,”PERSON 2”,22,..), (“ID-3”,”PERSON 2”,19,..),…..
}

If the `Person` list contains any `id`'s which are not mentioned in the `id` list then those values should be at the end of the sorted list.
___________________
Edited: This is my current way in Java. I am hoping for a better way than this:

public static List<Person> getSortList(List <Person> unsortedList, List<String> orderList){

if(unsortedList!=null && !unsortedList.isEmpty() && orderList!=null && !orderList.isEmpty()){
List sortedList = new ArrayList<OpenHABWidget>();
for(String id : orderList){
Person found= getPersonIfFound(unsortedList, id); // search for the item on the list by ID
if(found!=null)sortedList.add(found); // if found add to sorted list
unsortedList.remove(found); // remove added item
}
sortedList.addAll(unsortedList); // append the reaming items on the unsorted list to new sorted list
return sortedList;
}
else{
return unsortedList;
}

}

public static Person getPersonIfFound(List <Person> list, String key){
for(Person person : list){
if(person.getId().equals(key)){
return person;
}
}
return null;
}
Reply

#2
I would do something like (in pseudocode, since i don't know what your code looks like)

listOfPersons = [{2,Bob},{3,Claire},{1,Alice}]
orderList = [1,3,2]
sortedList = []
for(id in orderList)
person = listOfPersons.lookup(id)
sortedList.add(person)

And the lookup would be easier if you would have a map (id-> person) rather than a listOfPersons.
Reply

#3
Try the below code.





Map<String, Person> personMap=new HashMap<>(); // create a map with key as ID and value as Person object
List<String> orderList=new ArrayList<>(); // create a list or array with ID order
List<Person> outputList=new ArrayList<>(); //list to hold sorted values

//logic

// to sort Person based on ID list order
for (String order : orderList) {
if(personMap.containsKey(order)){
outputList.add(personMap.get(order));
personMap.remove(order);
}
}

// logic to add the Person object whose id is not present in ID order list
for (Entry<String, Person> entry : personMap.entrySet())
{
int lastIndex=outputList.size();
outputList.add(lastIndex, entry.getValue());
lastIndex++;
}

Now, the `outputList` will have the values that you are expecting...
Reply

#4
Following code will convert Person list to a `Map` where key will be the ID and value will be the Person object itself. This `Map` will help to quick lookup. Then iterate over the ID's list the get the value from the `Map` and added to a another `List`.

fun main(args: Array<String>) {
// List of ID
val listId = listOf(2, 1, 3)

val list = listOf(Person(id = 1, name = "A"),
Person(id = 2, name = "B"),
Person(id = 3, name = "C"))

val map: Map<Int, Person> = list.associateBy ({it.id}, {it})

val sortedList = mutableListOf<Person>()

listId.forEach({
sortedList.add(map[it]!!)
})

sortedList.forEach({
println(it)
})
}

data class Person(val id: Int, val name: String)

Output

Person(id=2, name=B)
Person(id=1, name=A)
Person(id=3, name=C)
Reply

#5
An efficient solution is to first create the mapping from the ID in the `ids` (your desired IDs order) to the index in that list:

val orderById = ids.withIndex().associate { (index, it) -> it.id to index }

And then sort your list of `people` by the order of their `id` in this mapping:

val sortedPeople = people.sortedBy { orderById[it.id] }

Note: if a person has an ID that is not present in the `ids`, they will be placed first in the list. To place them last, you can use a [`nullsLast`][2] comparator:

val sortedPeople = people.sortedWith(compareBy(nullsLast<String>()) { orderById[it.id] })


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through