Elisp'te iki değişkeni değiştirin


20

Varsayalım

(setq a 1 b 2)

Geçici bir değişken kullanmadan ave bkullanmadan değerleri nasıl zarif bir şekilde değiştirebilirim ?


Yıllar önce programlama örneklerinden takas operasyonunu hatırlasam da, böyle bir "takas" operasyonuna hiç ihtiyacım olduğunu düşünmüyorum. Öyleyse böyle bir şeye ihtiyacınız olduğunu nereden buldunuz?
Stefan

@Stefan bu sefer iki argüman alan bir işlev yazıyorum ve ilk argümanın ikisinden daha küçük olduğundan emin olmak istiyorum.
PythonNut

1
@PythonNut, ilk argümanı (min a b)ve ikincisine bağlayabilirsiniz (max a b). Bu bir çözüm. Bazıları bunun yeterli olduğu zaman bunun iki karşılaştırma gerektirdiğini iddia edecektir. Bunu daha işlevsel bir şekilde, örneğin yıkıcı bağlama kullanarak, bir karşılaştırma ile ele alabilirsiniz (cl-destructuring-bind (a . b) (if (< a b) (cons a b) (cons b a)) ...). Bu başka bir yol.
Mark Karpov

1
@ Doğru, ama, en azından benim için, el bombalarıyla sinek uçurmak gibi geliyor. cl-destructuring-bindbu iş için gülünç derecede güçlü bir araçtır.
PythonNut

Yanıtlar:


18

Bellek bana iyi hizmet ediyorsa ve kullanmaya istekliyseniz cl-lib:

(cl-rotatef a b)

Sorunun çözülmesinin Common Lisp yolu olduğuna dikkat edin.


20

Bu kullandığım zarif deyim ;-).

(setq a  (prog1 b (setq b  a)))

1
Hey, temiz. Performansın endişe kaynağı olduğunu aklımda tutacağım.
PythonNut

1
Ustaca ve basit.
Adı

1
Oh, hiçbir şekilde benimle orijinal değil. Ama muhtemelen ana kullanımımdır prog1.
Drew

1
cl-rotatefMakronun genişlediği hemen hemen budur .
abo-abo

6

Tamsayı ise:

(setq a (logxor a b))
(setq b (logxor a b))
(setq a (logxor a b))

:)


2
Tamlık için aşağıdaki klasiği de eklemelisiniz: a = a + b, b = a - b, a = a - b. Tercüme Emacs Lisp, tabii ki :-D
Mark Karpov

1
Doğru ve eksiksiz olması için asm veya C'de The XOR Trick'in her şey için çalıştığına dikkat çekeceğim; kayıtları, bellek, ints, yüzen, yapıları, dizeleri (eşit uzunluk) ... Lisp sadece bence ints. Büyük bellek blokları için geçici arabelleğe gerek yoktur.
jtgd

@jtgd: Büyük bellek blokları için, küçük bir arabellekle parça parça takas yapabilirsiniz.
Clément
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.