kotlin 根据其他列表的顺序对列表进行排序[duplicate]

egdjgwm8  于 2022-11-16  发布在  Kotlin
关注(0)|答案(4)|浏览(206)

此问题在此处已有答案

Guava way of sorting List according to another list?(6个答案)
五年前就关门了。
我需要对Person对象的列表进行排序(List<Person>,其中每个Person对象都有一些属性,如id(唯一)、nameage等)。
排序顺序基于另一个列表。该列表包含一组Personid(已排序的List<String>)。
使用Kotlin或Java将List<Person>排序为与id列表相同的顺序的最佳方法是什么?
示例:

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

已排序ID列表:

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

排序后的Person列表应为:

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

如果Person列表包含id列表中未提及的任何id,则这些值应位于排序列表的末尾。
编辑:这是我目前在Java中的方式。我希望有比这更好的方式:

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;
}
ruoxqz4g

ruoxqz4g1#

一个有效的解决方案是首先创建从ids中的ID(您所需的ID顺序)到该列表中的索引的Map:

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

然后按照id在这个Map中的顺序对people列表进行排序:

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

注意:如果人员的ID不在ids中,则会将其放在清单的最前面。若要将其放在最后,您可以使用nullsLast比较器:

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

vddsk6oq2#

我会这样做(用伪代码,因为我不知道你的代码是什么样子的)

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

如果你有一个map(id-〉person)而不是listOfPersons,查找会更容易。

a2mppw5e

a2mppw5e3#

请尝试以下代码。

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++;
    }

现在,outputList将具有您所期望的值...

00jrzges

00jrzges4#

以下代码将Person列表转换为Map,其中key是ID,value是Person对象本身。此Map有助于快速查找。然后遍历ID列表,从Map获取值,并将其添加到另一个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)

输出量

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

相关问题