2016-08-21 3 views
4

In Kotlin, Was ist der beste Weg, um durch ein Android Cursor-Objekt zu iterieren und die Ergebnisse in eine Liste?Kotlin auf Android: einen Cursor auf eine Liste setzen

Mein Auto-konvertierte Java:

val list = ArrayList<String>() 
while (c.moveToNext()) { 
    list.add(getStringFromCursor(c)) 
} 

Gibt es einen idiomatischen Weg? Insbesondere kann dies in einer einzigen Zuweisung einer Nur-Lese-Liste erfolgen? Z ....

val list = /*mystery*/.map(getStringFromCursor) 

... oder eine andere Anordnung, wo die Liste voll ausgebildet zugeordnet ist.

Antwort

6

Dies ist, was ich mit am Ende ging, kotlin.sequences.generateSequence mit ...

val list = generateSequence { if (c.moveToNext()) c else null } 
     .map { getStringFromCursor(it) } 
     .toList() 

Mein erster Versuch war ein wenig kürzer:

val list = (1 .. c.count).map { 
    c.moveToNext() 
    getStringFromCursor(c) 
} 

Beide Versionen auf dem Cursor verlassen anfänglich positioniert ist, vor dem ersten Datensatz. Die zweite würde werfen, wenn das nicht der Fall wäre, während die erste eine kürzere Liste zurückgeben würde.

+0

Hm und was über den ersten Artikel? Ich denke, das wird besser sein: 'fun Cursor.asSequence(): Sequenz = generateSequence (seed = takeIf {it.moveToFirst()}) {takeIf {it.moveToNext()}}' – ddmytrenko

+0

Ein frischer Cursor ist positioniert Vor dem ersten Datensatz wird der erste c.moveToNext() zum ersten Datensatz verschoben. –

0

Ihr erster Vorschlag ist richtig. Sie können den Cursor nicht zuordnen.

+1

OK. Ich habe nicht wirklich erwartet, dass ich das direkt machen könnte. Ich fragte mich, ob es eine idiomatische Art und Weise gibt (nicht unbedingt "Karte" verwenden - ich habe die Frage aktualisiert, um zu klären). –

+0

Es spielt keine Rolle, dass Sie 'map' verwendet haben. Das kann man in Kotlin nicht machen. –

3

Cursor s sollen faul sein, also gibt es keine offensichtliche map. Anko (ANdroid KOtlin von JetBrains) hat jedoch eine Erweiterungsmethode, die Ihnen bei der Zuordnung Cursor hilft.

Die Methode heißt Cursor.parseList(parser). Here können Sie die vollständige Implementierung finden. Die Verwendung sollte geradlinig sein. Und here sind einige offizielle Dokumente auf SQLite und Parsing Cursor mit anko.

+0

Anko sieht nützlich aus. Es scheint jedoch keine Funktion zu haben, die das Cursor-Objekt an meine existierende 'getStringFromCursor'-Funktion senden könnte. Es sendet nur ein Array oder eine Map mit Spaltenwerten. Da ich hoffe, meine App nach und nach auf Kotlin umzustellen, ist das ein Problem. (Die Quelle zeigt mir jedoch, wie man eine geeignete Erweiterungsfunktion schreibt, also danke dafür.) –

+0

Ich weiß nicht, wie Ihr 'getStringFromCursor' aussieht, aber möglicherweise kann er folgendermaßen implementiert werden: ' cursor.parseList { it ["column_name_with_string"]} ' oder ' val COLUMN_INDEX = 2' 'cursor.parseList {it [COLUMN_INDEX]}' – rafal

+0

Ja, der Anko-Weg sieht ziemlich gut aus, aber in diesem Fall schreibe ich den Testcode um und Ich möchte eine vorhandene Funktion testen (die einen Cursor nimmt und eine Zeichenfolge für diesen Datensatz zurückgibt). Anko verbirgt das Cursor-Objekt, was bedeutet, dass ich es nicht an die bestehende Funktion übergeben kann: Es bedeutet, dass ich beide Dinge neu schreiben müsste. –

Verwandte Themen