ForEach-Schleife in Mathematica
Ich würde gerne so etwas wie dieses:
each[i_, {1,2,3},
Print[i]
]
Oder, mehr allgemein, zu destructure beliebige Sachen in der Liste sind Sie Durchlaufen, wie:
each[{i_, j_}, {{1,10}, {2,20}, {3,30}},
Print[i*j]
]
In der Regel, die Sie verwenden möchten oder andere Map rein funktionale Konstrukte und meiden einen nicht-funktionalen Programmierung Stil, wo Sie mit Seite Auswirkungen. Aber hier ist ein Beispiel, wo ich denke, eine for-each-Konstrukt ist äußerst nützlich:
Sagen, ich habe eine Liste von Optionen (Regeln), dass ein paar Symbole mit Ausdrücken, wie
attrVals = {a -> 7, b -> 8, c -> 9}
Nun möchte ich, um eine hash-Tabelle, wo ich die offensichtliche Zuordnung dieser Symbole, um diese zahlen. Ich glaube nicht, dass es ein sauberer Weg zu tun, als
each[a_ -> v_, attrVals, h[a] = v]
Zusätzliche Testfälle
In diesem Beispiel wandeln wir eine Liste von Variablen:
a = 1;
b = 2;
c = 3;
each[i_, {a,b,c}, i = f[i]]
Nachdem die oben genannten, {a,b,c} ermitteln von {f[1],f[2],f[3]}. Beachten Sie, dass das bedeutet, dass das zweite argument von "jeder" gehalten werden soll, ungewichtete wenn es eine Liste.
Wenn die ungewichtete form ist keine Liste, es einschätzen soll, das zweite argument. Zum Beispiel:
each[i_, Rest[{a,b,c}], Print[i]]
Sollte drucken Sie die Werte von b und c.
Nachtrag: für jedes richtig, es sollte die Unterstützung Brechen, [] und Weiter[]. Ich bin mir nicht sicher, wie Sie Sie umsetzen. Vielleicht wird es brauchen, um irgendwie implementiert werden For -, While -, oder Do da sind nur loop-Konstrukte, die Unterstützung Brechen[] und Weiter[].
Und ein weiteres problem mit dem Antworten so weit: Sie Essen Zurück [s]. Das ist, wenn Sie mit einer ForEach-Schleife in eine Funktion und wollen die Rückkehr aus der Funktion innerhalb der Schleife, kann man nicht. Ausstellung Rückkehr in der ForEach-Schleife scheint zu funktionieren wie Weiter[]. Dies nur (warten) warf mich für eine Schleife.
InformationsquelleAutor der Frage |
Du musst angemeldet sein, um einen Kommentar abzugeben.
Neueren Versionen von Mathematica (6.0+) generalisierte Versionen von Do[] und Tabelle [], die fast genau, was Sie wollen, indem Sie eine Alternative form des "iterator" - argument. Zum Beispiel,
ist genau wie Ihre
Alterntatively, wenn Sie wirklich, wie das spezifische ForEach-syntax können Sie eine Reisetasche-Funktion implementiert, etwa so:
Diese Symbole verwendet als Variablen-Namen, nicht Muster, aber das ist, wie die verschiedenen eingebauten Kontrollstrukturen wie Do[] und [].
Reisetasche[] Funktionen ermöglichen Ihnen, um gemeinsam eine ziemlich große Auswahl an custom control-Strukturen. ReleaseHold[Halten[...]] ist in der Regel die einfachste Weise zu montieren eine Reihe von Mathematica-code, um später ausgewertet werden, und Block[{x = #}, ...]& können Variablen in Ihren Ausdruck Körper gebunden zu sein, was auch immer Werte, die Sie möchten.
In Reaktion auf dreeves' Frage unten, Sie können ändern, dieses Vorgehen zu ermöglichen, beliebigen destructuring mit der DownValues ein einzigartiges symbol.
Zu diesem Zeitpunkt, obwohl, ich denke Sie können es besser etwas zu bauen auf der Oberseite der Fälle.
Ich wie machen Null-explizite, wenn ich die Unterdrückung der Rückgabewert einer Funktion. BEARBEITEN: ich reparierte den Fehler hingewiesen werden dreeves unten; ich habe immer gerne mit
With
zu interpolieren, bewertet Ausdrücke inHold*
Formen.InformationsquelleAutor der Antwort
Ich bin Jahre zu spät zur party hier, und das ist vielleicht mehr eine Antwort auf die "meta-Frage", aber etwas, was viele Menschen zunächst eine schwere Zeit haben, mit bei der Programmierung mit Mathematica (oder einem anderen funktionalen Sprachen) nähert sich einem problem aus funktioneller und nicht struktureller Sicht. Die Mathematica-Sprache hat strukturelle Konstrukte, aber es ist funktional an seinem Kern.
Betrachten Sie Ihr erstes Beispiel:
Mehreren Leuten darauf hingewiesen, kann dies ausgedrückt werden funktionell als
Scan[Print, {1,2,3}]
oderPrint /@ {1,2,3}
(obwohl Sie sollten zugunstenScan
überMap
wenn möglich, wie zuvor erläutert, aber das kann ärgerlich sein, zu Zeiten, da es keine infix-operator fürScan
).In Mathematica normalerweise gibt es ein Dutzend Möglichkeiten, alles zu tun, das ist manchmal schön und manchmal frustrierend. Mit dem im Verstand, betrachten Sie Ihre zweite Beispiel:
... die ist interessanter aus einer funktionalen Sicht.
Eine mögliche funktionelle Lösung ist, verwenden Sie stattdessen die Liste der Ersatz, z.B.:
...aber wenn die Liste sehr groß ist, dies wäre unnötig langsam, da wir tun, so genannte "pattern-matching" (z.B., auf der Suche nach Instanzen von {a, b} in der Liste und Zuweisung zu
i
undj
) unnötig.Gegeben, die ein großes array von 100.000 Paare,
array = RandomInteger[{1, 100}, {10^6, 2}]
können wir einen Blick auf einige timings:Regel-Ersatz ist ziemlich schnell:
... aber wir können es ein wenig besser, wenn wir die Vorteile der Ausdruck Struktur, wo jedes paar ist wirklich
List[i,j]
und geltenTimes
als der Leiter jedes Paares, sich jeder{i,j}
inTimes[i,j]
:Als bei der Implementierung von
ForEach[...]
obenCases
ist ausgesprochen suboptimal:... da
Cases
macht mehr Arbeit, als nur die Regel, Ersatz -, dass dort eine Ausgabe der übereinstimmenden Elemente ein-by-one. Es stellt sich heraus, dass wir eine viel besser, indem er das problem anders, und profitieren Sie von der Tatsache, dassTimes
istListable
und unterstützt vektorisierte operation.Den
Listable
Attribut bedeutet, dass eine Funktionf
wird automatisch ein thread über eine beliebige Liste von Argumenten:So, da
Times
istListable
wenn wir stattdessen hatte die Paare von zahlen als zwei separate arrays:Wowein bisschen schneller! Auch wenn die Eingabe war nicht vorgesehen, als zwei separate arrays (oder haben Sie mehr als zwei Elemente in jedem paar) wir können immer noch etwas tun, optimal:
Die moral von diesem Epos ist nicht so, dass
ForEach
ist nicht ein wertvolles Konstrukt im Allgemeinen, oder auch in Mathematica, aber das kann man oft die gleichen Ergebnisse zu erzielen, mehr und effizienter aus, wenn Sie arbeiten in einer funktionalen Denkweise, sondern als ein strukturelles.InformationsquelleAutor der Antwort
Den integrierten
Scan
im Grunde tut dies, obwohl es hässlichere:Es ist besonders hässlich, wenn Sie wollen destructure der Elemente:
Folgende Funktion verhindert die Hässlichkeit, die durch Umwandlung
pattern
zubody
für jedes elementlist
.die verwendet werden können, wie im Beispiel in der Frage.
PS: Die akzeptierte Antwort, die mich veranlasst hat, wechseln Sie zu dieser, das ist, was ich bisher immer da und es scheint gut zu funktionieren (außer für die Einschränkung ich an die Frage):
InformationsquelleAutor der Antwort
Dem eingebauten Map-Funktion genau das tut, was Sie wollen. Es kann verwendet werden, in langer form:
Map[Print, {1,2,3}]
oder kurzer hand
Drucken /@ {1,2,3}
In Ihrem zweiten Fall, die Sie verwenden würden, "Print[Times@@#]&/@{{1,10}, {2,20}, {3,30}}"
Ich würde empfehlen, das Lesen der Mathematica-Hilfe auf der Karte, MapThread, Anwenden und Funktion. Sie nehmen etwas gewöhnungsbedürftig, aber sobald Sie sind, werden Sie nie wollen zurück zu gehen!
InformationsquelleAutor der Antwort
Hier ist eine leichte Verbesserung auf der Grundlage der letzten Antwort von dreeves, die es erlaubt anzugeben, das Muster ohne Leerzeichen (die syntax ähnlich wie in anderen Funktionen, wie Tisch-oder Do) und mithilfe der level-argument der Fälle
Tests:
InformationsquelleAutor der Antwort
Mathematica haben, map-Funktionen, so können sagen, Sie haben eine Funktion
Func
unter einem argument. Dann schreiben Sie einfachDer Rückgabewert ist eine Liste der angewendeten Funktion auf jedem element in der Liste.
zurück
{False,True,False,False}
InformationsquelleAutor der Antwort
Dank Pillsy und Leonid Shifrinhier ist, was ich jetzt mit:
InformationsquelleAutor der Antwort