Elispの2つの変数を交換する


20

私が持っていると仮定します

(setq a 1 b 2)

どのように私はエレガントの値入れ替えることができますaし、b一時的な変数を使用せずに?


私は何年も前のプログラミング例からのスワップ操作を覚えていますが、そのような「スワップ」操作が必要だとは思いません。それで、あなたはどこでそのようなものが必要だと思いますか?
ステファン

今回、@ Stefanは、2つの引数を取る関数を作成しています。最初の引数が2つのうち小さい方であることを確認したいと思います。
PythonNut

1
@ PythonNut、1番目の引数をにバインドし(min a b)、2番目の引数をにバインドできます(max a b)。これは1つの解決策です。1人で十分な場合、2回の比較が必要であると主張する人もいるでしょう。たとえば、バインドを破壊するなど、より機能的な方法で1回の比較で処理でき(cl-destructuring-bind (a . b) (if (< a b) (cons a b) (cons b a)) ...)ます。これは別の方法です。
マークカルポフ

1
@Mark true。しかし、少なくとも私には、手rena弾でハエをたたくように感じます。cl-destructuring-bindこの仕事のための途方もなく強力なツールです。
PythonNut

回答:


18

メモリがうまく機能し、使用したいcl-lib場合:

(cl-rotatef a b)

これがCommon Lispの問題解決方法であることに注意してください。


20

これは私が使用するエレガントなイディオムです;-)。

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

1
ねえ、それはきちんとしている。パフォーマンスが問題になる場合は、このことを心に留めておきます。
PythonNut

1
独創的でシンプル。
名前

1
ああ、それは決して私には独創的ではありません。しかし、それはおそらく私が使用する主な用途ですprog1
ドリュー

1
それはcl-rotatefマクロが展開するものです。
abo-abo

6

整数の場合:

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

:)


2
完全を期すために、次のクラシックも含める必要があります。a= a + b、b = a-b、a = a-b。もちろんEmacs Lispに翻訳:-D
Mark Karpov

1
確かに、完全を期すために、asmまたはCではThe XOR Trickが何でも機能することを指摘します。レジスタ、メモリ、int、float、struct、strings(等しい長さ)... Lispではintだけだと思います。メモリの大きなブロックの場合、一時バッファを必要としないのは良いことです。
jtgd

@jtgd:大きなメモリブロックの場合、小さなバッファでセグメントごとにスワップを実行できます。
クレメント
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.