2016-12-12 2 views
0

Ich möchte wiederholt eine mapcat Operation über Eingabe durchführen. ZBWie mapcat lazily iterieren

(->> input 
    (mapcat my-fn) 
    (mapcat my-fn) 
    (mapcat my-fn) 
    (...)) 

Gibt es eine Möglichkeit, dies träge zu tun?

Ich versuchte

(->> input 
    (iterate #(mapcat my-fn %))) 

Aber das hält nicht eine flache Struktur.

+3

Können Sie ein Beispiel der gewünschten Ein-/Ausgänge zeigen? –

+0

@AlanThompson Ich werde nach der Arbeit Beispieleingabe erstellen. Vielen Dank. –

Antwort

2

machte ich ein konstruiertes Beispiel, wo wir eine Liste von Listen von Zahlen umkehren wollen und tun dann etwas Mathematik auf ihnen eine einzige Liste zu produzieren:

user> (def my-funs [reverse #(map inc %)]) 
#'user/my-funs 

user> (reduce (fn [answer-so-far next-function] 
       (mapcat next-function answer-so-far)) 
       [[[1 1 1] [2 2 2] [3 3 3]] 
       [[2 2 2] [3 3 3] [4 4 4]]] 
       my-funs) 
(4 4 4 3 3 3 2 2 2 5 5 5 4 4 4 3 3 3) 

Die verringern Funktion beginnt mit der ersten Liste der Listen und wendet dann die erste Funktion auf diese Liste von Listen an, um die Antwort bis jetzt zu erzeugen, dann nimmt sie die zweite Funktion und wendet sie auf die Antwort bis jetzt an, um die folgende Antwort zu produzieren. Wenn Sie an mehr Funktionen denken, können Sie so oft wie gewünscht fortfahren.

Ich vermute, dass es den Code nicht viel attraktiver machen wird, um zu betrachten.

1

flatten sollte funktionieren:

(->> input 
    (iterate #(mapcat my-fn %)) 
    flatten) 
+0

reduzieren Sie Squashes * alle Schichten * anstatt nur die Folgen zu verketten. also würde es mit '[[1 2 3] [[[1 2 3] 7 8]]]]] scheitern.' –

+0

Ursprüngliche Frage fragt nach einer flachen Struktur. Wenn nur die Verkettung der ersten Ebene gewünscht wird, verwenden Sie 'concat anwenden'. Hinweis: Beide Funktionen geben die Lazy-Sequenz zurück. – rmcv