Kotlin中如何通过ID获取两个Student列表的非共同元素?
_id in Kotlin Hey there! Let's work through your problem together. First up: Kotlin doesn't have a single built-in function that directly spits out non-common elements between two lists while only checking the _id field, but we can build exactly what you need using existing collection functions with a few simple fixes.
Why Your Previous Approaches Failed
Let's break down where things went wrong with your two attempts:
- Approach 1: The filter condition has a logic mix-up. You used
prefStudents.any { it._id == students._id }, which checks if the current student exists withinprefStudentsitself (notstudentsList). This means you're filteringprefStudentsto match itself, then subtracting that fromprefStudents—you'll always end up with an empty list. - Approach 2: After combining lists and getting distinct elements by
_id, subtracting this fromprefStudentsremoves all shared students and any uniqueprefStudentsentries that appeared first instudentsList. This doesn't isolate the truly non-common elements.
Correct Implementations
Let's cover two common scenarios you might need:
1. Get Elements Present in Either List But Not Both (Symmetric Difference)
This gives you all students that exist in one list but not the other (like student 3 in your example):
internal fun getSymmetricDistinctStudents(studentsList: List<Student>, prefStudents: List<Student>): List<Student> { // Convert IDs to sets for fast lookup val studentIds = studentsList.map { it._id }.toSet() val prefIds = prefStudents.map { it._id }.toSet() // Get IDs unique to either list val nonCommonIds = studentIds.symmetricDifference(prefIds) // Collect all students matching these non-common IDs return (studentsList + prefStudents).filter { it._id in nonCommonIds } }
If you're using a Kotlin version older than 1.4 (where symmetricDifference isn't available), compute it manually:
val nonCommonIds = (studentIds union prefIds) minus (studentIds intersect prefIds)
2. Get Elements Only in prefStudents (Not in studentsList)
Use this if you just want students that exist exclusively in the prefStudents list:
internal fun getPrefOnlyStudents(studentsList: List<Student>, prefStudents: List<Student>): List<Student> { val studentIdSet = studentsList.map { it._id }.toSet() return prefStudents.filter { it._id !in studentIdSet } }
3. Get Elements Only in studentsList (Not in prefStudents)
The reverse of the above—for students exclusive to the main list:
internal fun getStudentsOnlyStudents(studentsList: List<Student>, prefStudents: List<Student>): List<Student> { val prefIdSet = prefStudents.map { it._id }.toSet() return studentsList.filter { it._id !in prefIdSet } }
How These Work
Using Set for IDs makes lookups O(1) (way faster than checking any() on a list, which is O(n) per element). This ensures the solution is efficient even for larger lists.
Testing with your example:
studentsList = [Student1, Student2, Student3]prefStudents = [Student1, Student2]getSymmetricDistinctStudentsreturns[Student3]getPrefOnlyStudentsreturns an empty list (all pref students are in the main list)getStudentsOnlyStudentsreturns[Student3]
内容的提问来源于stack exchange,提问作者Sanoop Surendran

