2016-06-22 10 views
2

私はの先物を持っていますが、それぞれは次のような配列を返します。Iterable[Future[Seq[Int]]]結果として、先物から返された配列の連結である配列が必要です。Seq[Int]スカラ先物順次怠惰実行

事は、私は配列のみを結果の最初のn要素を必要とするので、私は常にすべての先物を実行する必要がないことです。私はまた、それを達成するためにいくつの先物が実行される必要があるかを事前に知っていません(おそらく、最初のものが十分に戻ってくるでしょう、おそらくすべてを実行しなければならないかもしれません)。

明らかに、自分の機能を順番に実行する必要があります。私はforeachとbreak/returnをすることができましたが、機能的なスタイルで表現したいと思います。

+1

注すでに 'Future'sの' Iterable'を持っている場合、彼らはすでに「開始」していること。 –

+0

@EndeNeuああ、これは非常に貴重なコメントです!だから、実際には、もうそれらを「キャンセル」する方法はありませんか? –

+0

しかし、本当に 'Iterable'で、' Seq'ではなく、実際に開始されるのですか?私はそれらを "オンデマンド"に初期化しますが、これは助けてはなりませんか? –

答えて

2

次のように動作し、外観が機能しているようです。私はこれが実際にどのように実行されるか、またはフードの下で動作するかについての知識は限られています。

これは容易にハードコード化された4パラメータが渡されDEFに平手打ちすることができます。

私は真ん中の将来の評価がいずれかの方法を発生する必要があるため、わずか4が要求されたにもかかわらず、5つの要素を返す必要があることを考え出しました。余分な要素を削除するのは簡単です。

val f = Iterable(Future(Seq(1,2,3)), Future(Seq(4,5)), Future(Seq(6,7,8))) 

val output = f.foldLeft(Future(Seq.empty[Int])){(previous, next) => 
    previous.flatMap{pSeq => 
     if(pSeq.length >= 4) { 
      Future(pSeq) 
     } else { 
      next.map(nSeq => pSeq ++ nSeq) 
     } 
    } 
} 

println(Await.result(output, Duration.Inf)) //List(1,2,3,4,5) 

私は好きではないビットはちょうど一貫した型を維持するために、今後のPSEQをラップしています。

EDIT:ヴィクトルの答えにジャスト応答(私は十分に高くないので、担当者はコメントできないと、それは少し私の答えに値を追加します)。ヴィクトルの答えは、それを読みやすくであっても

は、彼らが必要とされていない場合でも、完了するために、すべての先物のを待たなければなりません。例えば

以下と鉱山でFを置き換える:

val f = Iterable(Future(Seq(1,2,3)), Future(Seq(4,5)), Future(throw new Exception)) 

それはまだ、将来[反復処理可能[] int型のIterable [フューチャー[]]をオンヴィクトルの呼び出しFuture.sequenceに動作します]ので、すべてを完了する必要があります。

+0

私はそれを試してみましょう、ありがとう –

1

あなたはFuture.foldのいずれかを使用:

scala> import scala.concurrent._ 

scala> import ExecutionContext.Implicits.global 

scala> Future.fold(Iterable(Future(Seq(1,2,3)), Future(Seq(4,5)), Future(Seq(6,7,8))))(Seq.empty[Int])((prev, cur) => if(prev.size >= 4) prev else prev ++ cur) foreach println 

List(1, 2, 3, 4, 5) 

scala> 

それともFuture.foldがどのように実装されるかを見て、あなたが終了条件を追加します。 (基本的にfoldUntil)

+0

他の答えでコメントされている、これはすべての先物が必要ではない場合でも実行されます –

関連する問題