Je veux inverser une séquence dans le clojure sans utiliser la fonction Voici ce que j'ai proposé: P> inverse code> et le faire de manière récursive. user> (reverse-recursively '(1 2 3 4 5 6))
(6 5 4 3 2 1)
user> (reverse-recursively [1 2 3 4 5 6])
(6 5 4 3 2 1)
user> (reverse-recursively {:a 1 :b 2 :c 3})
([:c 3] [:b 2] [:a 1])
7 Réponses :
ACC code>, car l'entrée d'origine peut être vide (et c'est plus de code). LI>
- la déstructuration est cool. Li>
xxx pré> comme pour boucle code> / recur code> et le ACC code>, vous avez besoin d'un moyen de passer autour du travail liste inversée. C'est soit boucle code>, soit ou ajoutez un autre paramètre à la fonction (qui est vraiment ce que la boucle code> est de toute façon). P> ou utilisez une fonction de commande supérieure : p> xxx pré> ul>
Concernant "Utiliser une fonction de commande supérieure", consultez (Source Inverser) CODE>
RÉPEC ABORD lorsque cette fonction s'applique de la carte ({: A 1: B 2: C 3}).
Eh bien, techniquement, ma question était "inverse une séquence" non "inverser quoi que ce soit" inverse une carte ", donc je pense que ce problème ne l'excluait pas. Voici l'erreur, BTW: Clojure> (Reverse-Récursivement {: A 1: B 2}) Code> Java.lang.unsupportedoperationException: NTH Non pris en charge sur ce type: persistaparraymap code>
De plus, il semble que la boucle / recur est bien sûr nécessaire pour la récursion de la queue, mais elle est considérée comme une "odeur de code" dans le clojure: Twoguysarguing.WordPress.com/2010/07/26/...
@noahz en fait, l'article dit "boucle / recur est pas i> une odeur de code, mais se méfie de cela". Je suppose que ce qu'ils veulent dire préfère la carte, réduire, etc. en général, mais ils ne fourniront pas toujours une solution.
La solution pour permettre à tout de travailler avec la fonction ci-dessus (par exemple, des cartes), consiste à initialiser la boucle avec (SEQ Coll) code>, au lieu de Coll code>.
FWIW (inverse-récursivement ()) code> retournera (nil) code>. Ce problème est également résolu en utilisant (SEQ Coll) code>, bien que je préfère ne pas déstructurer dans la boucle code> (qui introduit un assez inutile: comme code> ), mais plutôt avoir un si-let code> à l'intérieur de la boucle.
Le : comme tout code> est nécessaire pour vérifier la condition de terminaison sans introduire des problèmes nul / faux-éléments. EDIT: NVM, j'ai compris ce que vous vouliez dire. Je fais habituellement cela aussi, mais je suis sur un coup de pied destructurants ces derniers temps.
(defn my-rev [col]
(loop [ col col
result []]
(if (empty? col)
result
(recur (rest col) (cons (first col) result)))))
Q1.The JVM can not optimize the recursion, a recursive function that would directly and stack overflow. Therefore, in Clojure, which uses the loop/recur. So, without using a function that recur deep recursion can not be defined. (which is also used internally to recur as a function trampoline.)Q2.a recursive function by recur, must be tail-recursive. If the normal recursive function change to tail-recursive function, so there is a need to carry about the value of a variable is required as the accumulator.
L'ordre d'une séquence de carte ne change pas l'exécution. Mais la commande doit être mise en œuvre.
Je ne comprends pas ton commentaire. "La commande doit être mise en œuvre?"
@noahz, (Rev {: A 1: B 2: C 3}) -> ([[: C 3] [: B 2] [: A 1]) n'est pas nécessairement le cas. Mon résultat de Clojure1.3.0 est ([: B 2] [: C 3] [: A 1])
Ah, parce que persistatarraymap code> in Clojure est non ordonné comme java.util.hashmap code>? C'est non intuitif.
Je connais. La carte n'est en général pas déterminée que la commande sait. Afin qu'ils aient été insérés comme indiqué dans l'exemple doivent nécessairement.
Oui à la question 1, c'est ce que j'ai créé pour ma réponse à la Récursion Koan (je ne pouvais pas vous dire si c'était une bonne pratique de clojure ou non).
(defn recursive-reverse [coll]
(if (empty? coll)
[]
(conj (recursive-reverse (rest coll)) (first coll) )))
Eh bien, essayez ceci: (recours récursif (Appliquer STR (SEQ (prise de 100 000 (répétez "FOO"))))) Code>
Assez juste, je viens d'arriver à la dernière partie de ce koan où la fonction factorielle déborde si vous ne le faites pas sans la construction de boucle / recurienne. Je suppose donc maintenant que je peux dire que ce n'est pas une bonne pratique :) - Bravo!
C'est vraiment élégant!
Dans la version actuelle de Clojure, une fonction intégrée appelée RSEQ code>. Pour quiconque passe par. P>
RSEQ CODE> nécessite que la séquence d'entrée soit réversible code>, ce qui le rend généralement inapproprié (ne fonctionne pas avec les listes code>, avec persistanceList < / Code>, avec Lazyseq code>, avec des chaînes). Il est conçu comme une optimisation des séquences pouvant être inversée en temps constant.
(defn reverse-seq [sss]
(if (not (empty? sss))
(conj (reverse-seq (rest sss)) (first sss))
)
)
(defn recursive-reverse [coll]
(if (empty? coll)
()
(concat (vector (peek coll)) (recursive-reverse (pop coll )))
)
)
and test:
user=> (recursive-reverse [1])
(1)
user=> (recursive-reverse [1 2 3 4 5])
(5 4 3 2 1)
Pour des salopropulseurs, il existe une autre méthode utilisant dans code>. Depuis dans des utilisations internes conj code> il peut être utilisé comme suit: (defn reverse-list
"Reverse the element of alist."
[lst]
(into '() lst))
Étiez-vous éventuellement tenter Ce problème 4Clojure ? :)
Non, je n'etais pas. "Inverser une chaîne récursivement" est un problème d'entrevue très courant.