Supposons que j'ai une séquence in f # Ceci est soigneusement géré par le myseq code> consistant en éléments de type
a code> et une fonction
f code> de type
a -> option code>, et je veux le premier résultat de type
Option code> c'est un
un code> résultant de l'application
f code> à tous Éléments de la séquence, sinon
Aucun code> si aucun résultat de ce type n'a été trouvé.
Trypick code>
Fonction: P > mySeq.iterator.flatMap(f).nextOption()
4 Réponses :
Vous n'avez pas besoin de l'itérateur du tout que vous pouvez simplement faire
Voici un test qui montre que mysq.find (f (_). ISDEfinefin) code> p>
trouver code> fonctionne immédiatement sans itérateur (heure est en microsecondes) p>
Quoi??? Si le tout premier résultat est un aucun code> alors je ne le veux pas. Pourquoi devrais-je appeler
.head code> dessus? Dans tous les cas, si cela calcule des éléments même après avoir trouvé le premier résultat non défini, il serait trop inefficace à mes besoins.
Je pensais que j'étais assez clair mais je suppose que non, j'ai donc révisé la réponse. Cela a-t-il aidé?
Afray Not - 1) Votre Head Code> doit être un
Heoption code> de toute façon et 2) Je ne veux que le premier résultat calculé et court-circuité.
Eh bien, j'étais un peu confus par le libellé de votre question, je suppose que c'est mieux maintenant que vous l'avez édité. Quoi qu'il en soit, je ferais cela avec la correspondance des motifs, donc j'ai fait un exemple rapide pour vous dans la réponse révisée.
Vous n'avez toujours pas besoin d'un homme itérateur que vous pouvez simplement mysq.find (f (_)! = Aucun) code>
Non, cela retournera les éléments de la séquence et non le résultat de l'application de f. Maintenant, vous devrez recompagner l'application de f.
Vous pouvez simplement mapper la fonction à nouveau man que la complexité d'exécution moyenne n'est toujours pas O (n) mysq.find (f (_). ISDEFINÉ) .MAP (F) CODE>
Look "homme", je ne veux pas calculer f code> deux fois si je n'ai pas besoin.
Malheureusement, mysq.itéator.flatmap (a => f (a)). Toseq.HeadOption code> p>
.toseq code> doit être appelé depuis
itérateur code> n'a pas
case code> méthode. P>
mais toseq code> renvoie
flux code> pour
itérateur code> qui est éventuellement évalué afin que des calculs inutiles ne se produisent pas. s> <- seulement avant SCALA 2.13 P>
DEF TRYPICK [A, B] (F: A => OPTION [B]) (myseq: SEQ [A]) = mysq.ativeatorator.flatmap (f). Cadhoption code> ne compile pas. Comment puis-je le faire compiler?
myseq.itéatator.flatmap (f) .nextoption code> sur scala 2.13
Je ne compterais pas sur toseq code> pour renvoyer un flux
code>. Par exemple. Sur 2.13, il renvoie une liste
code>.
Vous pouvez également l'implémenter vous-même:
scala> def myFn(int: Int) = if (int > 2) Some(int) else None myFn: (int: Int)Option[Int] scala> tryPick(myFn, List(1, 0, -2, 3)) res0: Option[Int] = Some(3)
Merci. Je cherchais efficacement plus plus d'idiomatique; Je vais probablement coller à ma solution d'origine pour l'instant. Upvoted.
voir: p> trypick code> est presque équivalent à
CollectFirst code>. Sauf que
collectFirst code> fonctionne avec un
partialfunction code>. Donc, le plus proche que vous obtiendrez est probablement:
myseq.flatmap (f). Thead code>
@Bogdanvakulenko ces éléments calculeront-ils même après avoir trouvé le premier résultat code> isdefinefinine code>? Si oui, ce serait trop inefficace.
Il le fera, mais vous pouvez utiliser Itérateur pour l'empêcher comme vous l'avez fait:
mysq.itéatator.flatmap (f). Thead code>
ou convertir en flux:
mysq.to stream.flatmap (f). Thead code>
Ou vous pouvez simplement utiliser une collection paresseuse pour
mysq code>, vous n'avez donc pas à le convertir partout. Il peut être: flux (lazyliste), itérateur ou vue