web-dev-qa-db-ja.com

2つのリストから一般的でない要素を取得する-KOTLIN

同じモデルクラス(学生)の2つのリストがあります。サンプルの学生オブジェクト構造を以下に示します。

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

1つのリストには3つのオブジェクトと他の2つがあります。たとえば、リストAには1、2、3の生徒がいて、リストBには1、2があるとします。

だから私の質問は、珍しい要素を取得するための組み込み関数があるidだけを比較することによって?そうでない場合、どうすればこの問題を解決できますか?.

参考までに、私が解決するために作成した2つのアプローチを以下に示しますが、惨めに失敗しました。

アプローチ1。

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

アプローチ2。

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

どんな助けでも大歓迎です。

ありがとう

11
Sanoop

Ahmed Hegazyの投稿を達成するためのよりKotlinの方法。マップには、キーとカウントではなく、要素のリストが含まれます。

HashMapおよびKotlinビルトインの使用。 groupByは、Lambda(この場合はid)で定義されたキーとアイテムのリスト(このシナリオのリスト)でマップを作成します

次に、リストサイズが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 }
15
Mikezx6r

これはHashMapを使用したソリューションです。コードの方が優れている可能性がありますが、kotlinは非常に初めてです

fun getDistinctStudents(studentsList: List<Student>, prefStudents: List<Student>): List<Student> {
    val studentsOccurrences = HashMap<Student, Int>()
    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 }
}

生徒のクラスは、データクラスであるか、少なくともハッシュコードをオーバーライドし、キーとして使用するために等しい必要があります。

3
Ahmed Hegazy

私はこれが古い記事であることを知っていますが、より簡潔で短い解決策があると思います。上記で回答が承認されたMikezx6rのデータを使用して、以下のサンプルを参照してください。

val list1 = listOf(Student("1", "name1"), Student("2", "name2"))
val list2 = listOf(Student("1", "name1"), Student("2", "name2"), Student("3", "name2"))

val difference = list2.toSet().minus(list1.toSet())
3
Jonathan Kibet

最後に、Kotlinのドキュメントを検索した結果、解決策が見つかりました。私が探していた関数はfilterNotでした

これが私が試した完全なソリューションです。

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

珍しい要素を返しました。

1
Sanoop

誰かがより簡潔で短い解決策を思い付くまで、これは私が読むのに十分簡単だと思う実用的な解決策です:

internal fun getDistinctStudents(studentsList: List<Students>, prefStudents: List<Students>): List<Students> {
    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 ]
}

非常に大量の学生(数百人)がいる場合は、さまざまなステップにシーケンスを使用することを検討してください。最後の2つのリストを連結する前にフィルタリングすることも役立つ場合があります。

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

編集: 代わりにこの答え を参照してください。

1
zsmb13

現時点ではモバイルなのでテストできませんが、これはあなたが必要とするものでうまくいくかもしれません。 stdlibからの減算の使用 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/subtract.html

internal fun getDistinctStudents(studentsList: List<Students>, prefStudents: 
List<Students>): List<Students> {
    return prefStudents.subtract(studentList) + studentList.subtract(prefStudents)
}
1
user9287162