从两个列表中获取不寻常的元素 – KOTLIN

我有两个相同的模型类(STUDENT)的列表,示例学生对象结构如下,

{ "_id": "5a66d78690429a1d897a91ed", "division": "G", "standard": "X", "section": "Secondary", "lastName": "Sawant", "middleName": "Sandeep", "firstName": "Shraddha", "pin": 12345, "isEditable": true, "isTracked": false } 

一个列表有3个对象和其他2个。可以说,列表A有1,2,3个学生,而列表B有1个,2个

所以我的问题是有没有内置的function, 通过比较只是ID来获得不常见的元素? 如果不是,我怎么能解决这个问题。

仅供参考,以下是我已经解决的两个方法,但失败惨败。

方法1。

 internal fun getDistinctStudents(studentsList: List, prefStudents: List): List { val consolidated = prefStudents.filter { prefStudents.any { students: Students -> it._id == students._id } } return prefStudents.minus(consolidated) } 

方法2。

 internal fun getDistinctStudents(studentsList: List, prefStudents: List): List { val consolidatedStudents = studentsList + prefStudents val distinctStudents = consolidatedStudents.distinctBy{ it._id } return prefStudents.minus(distinctStudents) } 

任何forms的帮助将不胜感激。

谢谢

更多的Kotlin的方式来实现艾哈迈德Hegazy张贴。 该地图将包含一个元素列表,而不是一个键和计数。

使用HashMap和Kotlin内置插件。 groupBy使用Lambda中定义的键(本例中为id)创建一个Map,以及项目列表(此场景的List)

然后筛选列表大小不是1的条目。

最后,将其转换为单个学生列表(因此flatMap调用)

 val list1 = listOf(Student("1", "name1"), Student("2", "name2")) val list2 = listOf(Student("1", "name1"), Student("2", "name2"), Student("3", "name2")) val sum = list1 + list2 return sum.groupBy { it.id } .filter { it.value.size == 1 } .flatMap { it.value } 

这是使用HashMap的解决方案,代码可能会更好,但我对kotlin很新

 fun getDistinctStudents(studentsList: List, prefStudents: List): List { val studentsOccurrences = HashMap() val consolidatedStudents = studentsList + prefStudents for (student in consolidatedStudents) { val numberOfOccurrences = studentsOccurrences[student] studentsOccurrences.put(student, if(numberOfOccurrences == null) 1 else numberOfOccurrences + 1) } return consolidatedStudents.filter { student -> studentsOccurrences[student] == 1 } } 

你的学生类应该是一个数据类或者至少覆盖散列码,等于被用作一个键。

直到有人提出一个更简洁,更短的解决方案,我认为这个工作很容易阅读:

 internal fun getDistinctStudents(studentsList: List, prefStudents: List): List { val studentsIds = studentsList.map { it._id } // [ 1, 2, 3 ] val prefStudentIds = prefStudents.map { it._id } // [ 1, 2 ] val commonIds = studentsIds.intersect(prefStudentIds) // [ 1, 2 ] val allStudents = studentsList + prefStudents // [ Student1, Student2, Student3, Student1, Student2 ] return allStudents.filter { it._id !in commonIds } // [ Student3 ] } 

如果你的学生数量非常大(数百),考虑使用不同步骤的序列,在连接最后两个列表之前过滤可能也有帮助:

 val filteredStudents = studentsList.filter { it._id !in commonIds } val filteredPrefStudents = prefStudents.filter { it._id !in commonIds } return filteredStudents + filteredPrefStudents 

编辑:请参阅此答案 。

现在在手机上,所以我不能测试它,但这可能适用于你所需要的。 从stdlib中减去https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/subtract.html

 internal fun getDistinctStudents(studentsList: List, prefStudents: List): List { return prefStudents.subtract(studentList) + studentList.subtract(prefStudents) } 

最后经过一些搜索Kotlin文档我有解决方案。 我正在寻找的function是filterNot

这是我试过的完整解决方案。

 internal fun getDistinctStudents(studentsList: List, prefStudents: List): List { return prefStudents.filterNot { prefStudent -> studentsList.any { prefStudent._id == it._id } } } 

哪些返回了不寻常的元素。