2017-12-13 6 views
1

Kotlinは、ストリームに似たプログラミングを可能にする便利な拡張機能を提供しています。例えばネストされたリスト内の要素を最もうまく見つけるには?

、私は、リスト内の要素を探している場合、私はfindを使用することができます。

return list.find { n -> n>4 && n<6 } 

しかし、私は入れ子になっているのリストを持っている場合、これは私のために実用的ではないようです。それは私foは思わ

private fun findUsingForEach(data: List<List<Int>>, pred : (Int) -> Boolean) : Optional<Int> { 
    data.forEach { list -> 
     list.forEach { n -> 
      if(pred(n)) return Optional.of(n) 
     } 
    } 
    return Optional.empty() 
} 

forEachは、そのための適切なツールではないこと:luckyly私はKotlinと内側のラムダから返すことができます - 私はTUが、その後forEachを使用しています。これのためにもっと機能的な方法がありますか? filterが気になりますが、入れ子が問題を引き起こします。

follwingは、私は、関数abouveに使用するテストであること:

@Test 
open fun findTest() { 
    val data = listOf(listOf(1,2,3), listOf(3,4,5,6), listOf(), listOf(6,7,8)) 
    val e = findUsingForEach(data, { n -> n>4 && n < 6 }) 
    assertEquals(5, e.get()) 
} 

答えて

1

あなただけのコードを減らしたいとあなたが効率についてあまり気にしない場合は、これを試してみてください。

list.flatten().find { your pred here } 

それとも

list.flatMap { it }.find { your pred } 

か、新しいリストを作成していない便利なユーティリティ(とら速い/低メモリ)を作成します。

inline fun <T> Iterable<Iterable<T>>.forEachEach(f: (T) -> Unit) = 
    forEach { it.forEach(f) } 
2

あなたがリストをflattenできます

fun <T> Iterable<Iterable<T>>.flatten(): List<T>source

与えられたコレクション内のすべてのコレクションのすべての要素の単一のリストを返します。

val data = listOf(listOf(1, 2, 3), listOf(3, 4, 5, 6), listOf(), listOf(6, 7, 8)) 
data.flatten().find { n -> n > 4 && n < 6 } 

これは、順番にサブリストの要素を持つ単一のリストを返します。いつものようにfindを使うことができます。あなたの例では

{{1, 2, 3}, {3, 4, 5, 6}, {}, {6, 7, 8}} 

{1, 2, 3, 3, 4, 5, 6, 6, 7, 8} 

になり、このリストにfindの結果は5です。

ただし、これにより新しいリストが作成されます。

data.asSequence() 

をしてから、この順序であなたの操作を実行します:あなたはメモリを節約したい場合は

/** 
* Returns a single list of all elements from all collections in the given collection. 
*/ 
public fun <T> Iterable<Iterable<T>>.flatten(): List<T> { 
    val result = ArrayList<T>() 
    for (element in this) { 
     result.addAll(element) 
    } 
    return result 
} 

は、最初のリストからSequenceを作成します。

flattenのソースを見てみましょう
data.asSequence().flatten().find { n -> n > 4 && n < 6 } 

サイドノート:お客様のプレディケートn > 4 && n < 6は簡単ですyはn == 5に相当します。

+0

「asSequence」に言及するためのボーナスポイント。 +1 – towi

関連する問題