回答:
これは、2つの変数の値を交換するためのワンライナーです。
与えられた変数a
とb
:
b = [a, a = b][0];
以下のデモ:
var a=1,
b=2,
output=document.getElementById('output');
output.innerHTML="<p>Original: "+a+", "+b+"</p>";
b = [a, a = b][0];
output.innerHTML+="<p>Swapped: "+a+", "+b+"</p>";
<div id="output"></div>
[a, b] = [b, a];
。
Invalid left-hand side in assignment
エラーが発生しているため、ECMAScript 6のバージョンはまだテストできませんでした。
ES6(FirefoxおよびChromeは既にサポートしています(Destructuring Assignment Array Matching)):
let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);
あなたはこれを行うことができます:
var a = 1,
b = 2,
tmp;
tmp = a;
a = b;
b = tmp;
可読性と保守性のために、これは(少なくともJavaScriptでは)打ち負かすことはできません。コードを保守している人(6か月後を含む)は、何が起こっているのかを正確に把握できます。
これらは整数であるため、3番目の変数を使用せずに、任意の数の巧妙なトリック1を使用してスワップすることもできます。たとえば、ビットごとのxor演算子を使用できます。
let a = 1, b = 2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log('a is now:', a);
console.log('b is now:', b);
これはXORスワップアルゴリズムと呼ばれます。その動作理論は、このウィキペディアの記事で説明されています。
1 「有能なプログラマーは、自分の頭蓋骨のサイズが限られていることを十分に認識しています。したがって、彼は十分な謙虚さで仕事に取り組み、ペストのような巧妙なトリックを回避します。」— Edsger W. Dijkstra
ToInt32
内部メソッドを使用-ECMAScript 標準のセクション11.10を参照)。整数以外の数値については、正しい結果が生成されません。また、数値以外の値を32ビット整数に変換します。あなたが起動した場合a = "hi"
とb = "there"
、あなたが終わるa == 0
とb == 0
。
typeof a == 'boolean'
またはa === false
で機能しません。実数は機能しますが、最も近い整数に丸められるのではなく、ゼロに向かってフロアされます。
以下のコードは使用しないでください。それはない(単に二つの変数の値を交換するために推奨される方法の一時的な変数を使用そのために)。JavaScriptのトリックを示しているだけです。
このソリューションは、一時変数、配列、追加を1つだけ使用せず、高速です。実際、いくつかのプラットフォームでは、一時変数よりも高速な場合があります。
すべての数値で機能し、オーバーフローすることはなく、InfinityやNaNなどのエッジケースを処理します。
a = b + (b=a, 0)
これは2つのステップで機能します。
(b=a, 0)
b
の古い値に設定し、a
yields0
a = b + 0
a
古い値に設定しますb
,
であり、優先順位を設定するためにラップされています。コンマ演算子は、両方の引数(この場合はb=a
と0
)を評価し、最後の引数(この場合は)を返します0
。したがって、ここでb
はa
、を生成しながら、new をの古い値に設定する効果があります0
。
ここで仮定して、ワンライナーだa
とb
すでに存在しているとスワップされる必要が値を持っています:
var c=a, a=b, b=c;
@Kayが述べたように、これは実際には配列方式よりもパフォーマンスが優れています(ほぼ2倍高速)。
var a, b, tmp;
a = 1
; b = 2
; tmp=a, a=b, b=tmp;
個人的な好み。
一時的なスワップ変数またはXORを使用できます。
a = a ^ b
b = a ^ b
a = a ^ b
これは基本的な論理概念であり、XOR演算をサポートするすべての言語で機能します。
編集:コメントを参照してください。これが整数でのみ確実に機能することを伝えるのを忘れていました。質問のスレッドからの整数変数を想定
ES6の破壊的な割り当ては次のように使用できます。
let a = 10;
let b = 20;
[a, b] = [b, a];
console.log(a, b); // a = 20, b = 10
あなたの質問は「この変数のみで、オブジェクトではない」という貴重なものだったので、答えも貴重です。
変数a = 1、b = 2
a=a+b;
b=a-b;
a=a-b;
それはトリックであり、
そしてロドリゴ・アシスが言ったように、それは「短くなることができる」
b=a+(a=b)-b;
ES6の破壊:
配列を使用する: [a, b] = [b, a]; // my favorite
オブジェクトの使用: {a, b} = {a:b, b:a}; // not bad neither
これらの古典的なワンライナーをどうやって見逃すことができますか
var a = 1, b = 2
a = ({a:b, _:(b=a)}).a;
そして
var a = 1, b = 2
a = (_=b,b=a,_);
最後の1つはグローバル変数「_」を公開しますが、一般的なJavaScriptの慣例では、それを「ドントケア」変数として使用するため、問題にはなりません。
a = (_=b,b=a,_);
_
どういう意味ですか?なぜ宣言が必要ないのですか?
私はここに一種のプログラミングオリンピックを見る。もう1つのトリッキーな1行のソリューション:
b = (function(){ a=b; return arguments[0]; })(a);
arguments
ただ使用してくださいb = (function (x){ return x; })(a, a=b)
。
arguments
リストも変数になります。
a
にarguments[0]
パラメータとして渡すことで。
arguments
、その
var a = 5;
var b = 10;
b = [a, a = b][0];
//or
b = [a, a = b];
b = b[0];
//or
b = [a, b];
a = b[1];
b = b[0];
alert("a=" + a + ',' + "b=" + b);
2つのORを削除またはコメントして、1セットのコードで実行します
次のようにvarを交換できます。
var val1 = 117,
val2 = 327;
val2 = val1-val2;
console.log(val2);
val1 = val1-val2;
console.log(val1);
val2 = val1+val2;
console.log(val2);
ES6には、破壊的な割り当てがあり、次のことができます。
let a = 1;
let b = 2;
[b, a] = [a, b] // a = 2, b = 1
それは非常に簡単
です。詳細については、このリンクを参照してくださいES6配列分解構文を使用してくださいhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment[y, x] = [x, y]
ES5まで、2つの数値を交換するには、一時変数を作成してから交換する必要があります。しかしES6では、配列の構造化を使用して2つの数値を交換するのは非常に簡単です。例を参照してください。
let x,y;
[x,y]=[2,3];
console.log(x,y); // return 2,3
[x,y]=[y,x];
console.log(x,y); // return 3,2
このメソッドの実行速度が遅いと聞いたので:
b = [a, a = b][0];
varをオブジェクト(または配列)に格納する場合は、この関数が機能するはずです。
function swapVars(obj, var1, var2){
let temp = obj[var1];
obj[var1] = obj[var2];
obj[var2] = temp;
}
使用法:
let test = {a: 'test 1', b: 'test 2'};
console.log(test); //output: {a: 'test 1', b: 'test 2'}
swapVars(test, 'a', 'b');
console.log(test); //output: {a: 'test 2', b: 'test 1'}
IIFEを使用して、追加のパラメーターなしで2つの値を交換できます。
var a = 5, b =8;
b = (function(a){
return a
}(a, a=b));
document.write("a: " + a+ " b: "+ b);
ES6配列の非構造化は、2つの変数を交換するために使用されます。例を見る
var [x,y]=[1,2];
[x,y]=[y,x];
より簡単な方法:
x === 1
そしてy === 2
; しかし、解体後、x
is y
、つまり2
、およびy
is x
、つまり1
です。
ビットワイズを使用してスワップ
let a = 10;
let b = 20;
a ^= b;
y ^= a;
a ^= b;
「配列を使用する」単一行スワップ
[a, b] = [b, a]