从两个列表中获取不寻常的元素 – 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 } } }
哪些返回了不寻常的元素。