Sagen wir, ich habe eine Sequenz von 100 Elementen. Jedes 10. Element Ich möchte eine neue Liste der vorherigen 10 Elemente. In diesem Fall werde ich mit einer Liste von 10 Unterlisten enden.
Seq.take (10) sieht vielversprechend aus, wie kann ich es wiederholt aufrufen, um eine Liste von Listen zurückzugeben?
Ich habe eine Evolution von drei Lösungen. Keiner von ihnen behält die Reihenfolge der Eingabeelemente bei, was hoffentlich OK ist.
Meine erste Lösung ist ziemlich hässlich (mit ref-Zellen):
%Vor%Meine zweite Lösung hebt die Verwendung von Ref-Zellen in der ersten Lösung auf, erzwingt aber konsequenterweise den direkten IEnumerator-Zugriff (eine Seite hineinschieben, die andere herausziehen)!
%Vor%Meine dritte Lösung basiert auf der zweiten Lösung, außer dass sie "schummelt", indem sie eine Liste als Eingabe anstelle einer Sequenz verwendet. Dies ermöglicht die eleganteste Lösung mit Mustererkennung, wie Tomas angibt, fehlt mit seq (weshalb wir waren gezwungen, direkten Zugriff IEnumerator zu verwenden).
%Vor% Wenn es wichtig ist, die Reihenfolge der Elemente beizubehalten, können Sie zu diesem Zweck List.rev verwenden. Ändern Sie beispielsweise in Lösung2 die letzte Zeile der Funktion split
in:
Ich denke, dass die Lösung von Brian wahrscheinlich die vernünftigste einfache Option ist. Ein Problem mit Sequenzen ist, dass sie nicht einfach mit dem üblichen Mustervergleich (wie Funktionslisten) verarbeitet werden können. Eine Möglichkeit, dies zu vermeiden, wäre die Verwendung von LazyList
von F # PowerPack.
Eine weitere Option besteht darin, einen Berechnungsgenerator für das Arbeiten mit IEnumerator
type zu definieren. Ich habe kürzlich so etwas geschrieben - Sie können es hier bekommen . Dann können Sie etwas schreiben wie:
Dies ermöglicht die Verwendung einiger funktionaler Muster für die Listenverarbeitung - vor allem können Sie dies als eine gewöhnliche rekursive Funktion schreiben (ähnlich der, die Sie für Listen / faule Listen schreiben würden), aber es ist zwingend erforderlich unter dem Cover (der let!
constructo von iter
nimmt das nächste Element und modifiziert den Enumerator).
Verwenden Sie im Zweifelsfall die Falte.
%Vor% Dies hat den Vorteil, dass es voll funktionsfähig ist und dennoch jedes Element der Eingabesequenz nur einmal (*) berührt (im Gegensatz zu den oben vorgeschlagenen Seq.take
+ Seq.skip
-Lösungen).
(*) Angenommen, O (1) Seq.append. Ich sollte es auf jeden Fall hoffen.
Ich fand, dass dies die schnellste ist:
%Vor%d. Blenden Sie die Liste ein, zippen Sie mit einer Liste von Ganzzahlen, entfernen Sie alle überlappenden Elemente und legen Sie dann den ganzzahligen Teil des Tupels ab.
Tags und Links f#