Cara menukar dua variabel dalam JavaScript

Jawaban:

321

Berikut ini adalah satu-liner untuk menukar nilai dua variabel.
Variabel yang diberikan adan b:

b = [a, a = b][0];

Demonstrasi di bawah ini:

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>

showdev
sumber
264
+1. Tapi versi terpendek akan di ECMAScript 6: [a, b] = [b, a];.
dfsq
8
@Kay: Tampaknya juga jauh lebih lambat menggunakan array daripada variabel ketiga: http://jsperf.com/swap-array-vs-variable Saya hanya menguji ini di Chrome. Saya belum dapat menguji versi ECMAScript 6 karena saat ini memberikan Invalid left-hand side in assignment kesalahan.
Tidak
2
@ FrançoisWahl Poin bagus. Saya pikir sebagian besar jawaban di sini akan berfungsi dan cukup setara. Saya kira ini merupakan trade off antara penggunaan variabel sementara, jumlah kode, dan kecepatan.
showdev
3
@ FrançoisWahl, saya tidak akan menduga bahwa solusi ini jauh lebih lambat. Lihat juga: jsperf.com/swap-array-vs-variable/3
kay - SE jahat
3
@showdev Baca kutipan Dijkstra dalam jawaban Ted Hopp.
Brian McCutchon
185

ES6 (Firefox dan Chrome sudah mendukungnya (Pencocokan Susunan Tugas Penentuan)):

let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);

Pedro Justo
sumber
2
ada yang tahu nama semacam swap di ES6?
derek
6
@derek - Saya pikir ini disebut pencocokan array , suatu bentuk tugas penataan .
Ted Hopp
4
Ini tampaknya sekitar 35 kali lebih lambat daripada metode variabel ketiga pada nodejs 7.4.0 / win7 64. Tapi itu jelas rapi.
mkey
5
Sejak V8 versi 6.8, bertukar variabel dengan destruksi array harus secepat dengan variabel sementara ( v8project.blogspot.com/2018/06/v8-release-68.html ).
Ruben Verborgh
120

Kamu bisa melakukan ini:

var a = 1,
    b = 2,
    tmp;
tmp = a;
a = b;
b = tmp;

Untuk keterbacaan dan pemeliharaan, ini tidak dapat dikalahkan (setidaknya dalam JavaScript). Siapa pun yang memelihara kode (termasuk Anda enam bulan dari sekarang) akan tahu persis apa yang terjadi.

Karena ini adalah bilangan bulat, Anda juga dapat menggunakan sejumlah trik pintar 1 untuk bertukar tanpa menggunakan variabel ketiga. Misalnya Anda dapat menggunakan bitor xor operator:

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);

Ini disebut algoritma swap XOR. Teori operasinya dijelaskan dalam artikel Wikipedia ini .

1 "The programmer yang kompeten sepenuhnya menyadari keterbatasan ukuran tengkorak sendiri. Karena itu ia mendekati tugasnya dengan kerendahan hati penuh, dan menghindari trik pintar seperti wabah." - Edsger W. Dijkstra

Ted Hopp
sumber
Xor akan bekerja dengan semua tipe data. Ini adalah trik pengurangan yang hanya akan bekerja dengan angka.
Rob Grant
11
@RobertGrant - Operator xor dalam JavaScript mengubah operandnya menjadi bilangan bulat 32-bit (menggunakan ToInt32metode internal — lihat Bagian 11.10 dari standar ECMAScript ). Itu tidak menghasilkan hasil yang benar untuk nilai numerik non-integer. Ini juga mengkonversi nilai-nilai non-numerik ke integer 32-bit. Jika Anda mulai dengan a = "hi"dan b = "there", Anda berakhir dengan a == 0dan b == 0.
Ted Hopp
1
Trik ini berfungsi dengan semua tipe data, asalkan Anda tidak keberatan dengan hasil integer; nilai-nilai dilemparkan secara otomatis ke int32s. Ini berarti dapat bekerja dengan string numerik, Boolean (0/1), null (0), dan kosongkan array / objek (0). Meskipun tipe aslinya tidak diawetkan, jadi Boolean yang terpengaruh tidak akan bekerja dengan typeof a == 'boolean'atau a === false, misalnya. Bilangan real bekerja, kecuali mereka didasarkan pada nol versus dibulatkan ke bilangan bulat terdekat.
Beejor
1
@ Beejor - Dengan kata lain, ini bekerja dengan semua tipe data, kecuali itu tidak (kecuali mereka adalah nilai integer). Dalam buku saya, "swap" berarti "akhiri dengan setiap variabel yang memiliki nilai yang dimiliki variabel lain", bukan "convert to int32 lalu swap".
Ted Hopp
@TedHopp Cukup adil. Maksud saya "berfungsi" dalam hal fakta bahwa Anda dapat membuang tipe data apa pun padanya, tidak seperti di dalamnya berfungsi sebagai solusi swap yang baik. Saya setuju itu tidak terlalu berguna secara umum.
Beejor
58

Jangan gunakan kode di bawah ini. Ini bukan cara yang disarankan untuk menukar nilai dua variabel (cukup gunakan variabel sementara untuk itu). Itu hanya menunjukkan trik JavaScript.

Solusi ini tidak menggunakan variabel sementara, tidak ada array, hanya satu tambahan, dan cepat . Bahkan, kadang - kadang lebih cepat daripada variabel sementara di beberapa platform .
Ini bekerja untuk semua angka, tidak pernah meluap, dan menangani kasus tepi seperti Infinity dan NaN.

a = b + (b=a, 0)

Ini bekerja dalam dua langkah:

  • (b=a, 0)set bke nilai adan hasil lama0
  • a = b + 0set ake nilai lama darib
Ruben Verborgh
sumber
5
Versi temp var sedikit lebih cepat, dan lebih umum dan lebih mudah dibaca juga. jsperf.com/swap-two-numbers-without-tmp-var/9
Antimony
Apa artinya sintaks ini ()? bagaimana cara menghasilkan 0?
Pete Alvin
8
Operator dalam tanda kurung adalah operator koma ,, dan telah dibungkus untuk mengatur hak yang diutamakan. Operator koma mengevaluasi kedua argumennya (dalam hal ini b=adan 0) dan mengembalikan yang terakhir (dalam kasus ini 0). Jadi di sini, ia memiliki efek menetapkan nilai baru bke nilai lama a, sambil menghasilkan 0.
Ruben Verborgh
6
Apakah saya benar dalam berpikir ini hanya berfungsi untuk nilai numerik? Anda tidak dapat menggunakan ini dengan misalnya var a = "hello" b = "world" sebagai a = "world0".
Chris GW Green
3
@ChrisGWGreen:a = b + (b=a, "")
19

Sejak ES6, Anda juga dapat menukar variabel dengan lebih elegan:

var a = 1,
    b = 2;

[a, b] = [b, a];

console.log('a:', a, 'b:', b); // a: 2 b: 1
Peter
sumber
18

Ini adalah one-liner, dengan asumsi adan bsudah ada dan memiliki nilai yang perlu ditukar:

var c=a, a=b, b=c;

Seperti yang disebutkan oleh @Kay, ini sebenarnya berkinerja lebih baik daripada cara array (hampir 2x lebih cepat).

bobobobo
sumber
1
Seperti jawaban ideal saya, hanya saja saya lebih suka tidak mendeklarasikan ulang variabel a & b saat bertukar, dan menggunakan nama variabel eksplisit "tmp". Seperti var a, b, tmp; a = 1:; b = 2; tmp=a, a=b, b=tmp; Selera pribadi.
Johnny Wong
10

Gunakan variabel ketiga seperti ini:

var a = 1,
    b = 2,
    c = a;

a = b; // must be first or a and b end up being both 1
b = c;

DEMO - Menggunakan variabel ketiga


Nggak
sumber
10

Metode ES6 +: Sejak ES6, Anda dapat bertukar variabel dengan lebih elegan. Anda dapat menggunakan pencocokan susunan tugas penataan. Sederhana saja. var a = 10 b = 20;

[a, b] = [b, a]

console.log (a, b) // 20 10

Jalak Patoliya
sumber
10

Sekarang Anda akhirnya dapat melakukan:

let a = 5;
let b = 10;

[a, b] = [b, a]; // ES6

console.log(a, b);

mehulmpt
sumber
9

Anda bisa menggunakan variabel swap sementara atau XOR.

a = a ^ b
b = a ^ b
a = a ^ b

Ini hanya konsep logis dasar dan berfungsi dalam setiap bahasa yang mendukung operasi XOR.

edit: lihat Komentar. Lupa memberi tahu bahwa ini hanya berfungsi dengan integer. Diasumsikan variabel integer dari utas pertanyaan

DmiN
sumber
16
Bekerja untuk wawancara pemrograman dan kasus trivia umum lainnya. Namun, perhatikan, ini adalah cara yang agak bodoh untuk bertukar nilai dalam kehidupan nyata. Untuk satu hal, di JS, itu hanya bekerja dengan bilangan bulat.
cHao
1
@Kay Apa yang Anda maksud dengan "bukan hal yang nyata selama 30 tahun terakhir?" Saya menggunakan operator bitwise kapan pun masuk akal, yang sebenarnya cukup sering (misalnya, beralih ke boolean yang tidak diketahui)
Ben Harold
1
@cHao Operator Bitwise secara konsisten (dan sejauh ini) tercepat di mesin saya: jsperf.com/swap-array-vs-variable/2
Ben Harold
3
@ php_surgeon Saya mengubah biola sedikit sehingga kompiler tidak dapat menandai variabel sebagai mati. jsperf.com/swap-array-vs-variable/3 . Solusi temp var sekarang 1/4 lebih cepat daripada solusi xor swap
kay - SE jahat
1
@Kay Dalam situasi di mana ada sesuatu yang stabil, komentar baik, teknik tercepat, dan hanya digunakan di satu atau dua tempat, saya tidak melihat mengapa itu tidak akan baik-baik saja dalam kode produksi. Operasi bitwise pada umumnya adalah konsep yang sulit, jadi jika kode sudah menggunakan banyak dari mereka, pengelola harus terbiasa dengan mereka. Untuk sebagian besar kasus, itu jelas berlebihan. Saya hanya berpikir pernyataan selimut tidak selalu membantu; semuanya memiliki tempat, bahkan "goto" dan "eval".
Beejor
8

Anda dapat menggunakan penugasan penghancuran ES6 seperti:

let a = 10;
let b = 20;

[a, b] = [b, a]; 

console.log(a, b); // a = 20, b = 10
Manuel Abascal
sumber
7

Karena pertanyaan Anda berharga "Hanya variabel ini, bukan objek apa pun.", Jawabannya juga akan berharga:

var a = 1, b = 2

a=a+b;
b=a-b;
a=a-b;

itu tipuan

Dan seperti yang dikatakan Rodrigo Assis, "bisa lebih pendek"

 b=a+(a=b)-b;

Demo: http://jsfiddle.net/abdennour/2jJQ2/

Abdennour TOUMI
sumber
1
Kesalahan yang sama dengan jawaban @ DmiN.
kay - SE jahat
dimana kamu menemukan kesalahan? Itu tidak terhormat
Abdennour TOUMI
2
@AbdennourToumi Saya pikir Kay merujuk pada fakta bahwa jawaban Anda hanya bekerja dengan bilangan bulat.
showdev
1
@showdev: Harap baca lagi pertanyaan: "Hanya variabel ini, bukan objek apa pun" .... jawaban saya berharga sebagai pertanyaan. Saya meminta Anda untuk menandai komentar. Saya ulangi: Ini tidak terhormat.
Abdennour TOUMI
1
Pembicaraan ini aneh. @AbdennourTOUMI - variabel tidak sama dengan integer. Anda dapat memiliki variabel yang mengarah ke objek, string, fungsi, null, dll.
Rob Grant
6

ES6 Destrukturisasi:

Menggunakan array: [a, b] = [b, a]; // my favorite

Menggunakan objek: {a, b} = {a:b, b:a}; // not bad neither

Flavien Volken
sumber
4

Bagaimana kita bisa melewatkan oneliners klasik ini

var a = 1, b = 2
a = ({a:b, _:(b=a)}).a;

Dan

var a = 1, b = 2
a = (_=b,b=a,_);

Yang terakhir memperlihatkan variabel global '_' tetapi yang seharusnya tidak menjadi masalah seperti konvensi javascript biasa adalah menggunakannya sebagai variabel 'tidak peduli'.

Teemu Ikonen
sumber
1
Ada salah ketik di yang kedua. Seharusnyaa = (_=b,b=a,_);
Mageek
Apa arti garis bawah _? Mengapa tidak perlu deklarasi?
hari
garis bawah hanyalah nama variabel global, Anda dapat menggantinya dengan nama yang valid. misalnya a = (justsomething = b, b = a, justsomething)
Teemu Ikonen
6
Oh tidak, jangan gunakan vars magic-global yang tidak diumumkan! Itu cara yang pasti untuk bug mengerikan dalam kehidupan nyata.
oriadam
Siapa pun yang menggunakan underscore.js akan sangat tidak senang jika mereka mencoba yang kedua.
Ted Hopp
3

Saya melihat semacam olimpiade pemrograman di sini. Satu solusi satu-baris yang lebih rumit:

b = (function(){ a=b; return arguments[0]; })(a);

Fiddle: http://jsfiddle.net/cherniv/4q226/

Cherniv
sumber
2
Tidak perlu menggunakan yang lambat arguments, lakukan saja b = (function (x){ return x; })(a, a=b).
Ruben Verborgh
1
@ RubenVerborgh ya tetapi dengan argumen kami tidak mendefinisikan variabel ketiga!
Cherniv
1
Secara teknis, argumentsdaftar juga akan menjadi variabel.
Ruben Verborgh
1
Nah, Anda menetapkan auntuk arguments[0]dengan melewatkan sebagai parameter.
Ruben Verborgh
1
@ RubenVerborgh ya, tetapi Anda tidak membuat argumentsdan penugasannya terjadi "di belakang layar"
Cherniv
3

Swapping baris tunggal

a = a^b^(b^=(a^b));
Saruselvi
sumber
3
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);

hapus atau komentari 2 // atau dan jalankan dengan satu set kode

http://jsfiddle.net/USdv8/57/

Thilak Raj
sumber
2

Kami dapat menukar var seperti ini:

var val1 =  117,
    val2 = 327;

val2 = val1-val2; 
console.log(val2);
val1 = val1-val2;
console.log(val1);
val2 = val1+val2;
console.log(val2);
Mohammed Javed
sumber
2

Di ES6 sekarang ada tugas penataan dan Anda dapat melakukan:

let a = 1;
let b = 2;
[b, a] = [a, b]  // a = 2, b = 1
Stanislav Bozhanov
sumber
1
let a = 2, b = 4;
[b, a] = [a, b];

pendekatan yang lebih verbal akan

let a = 2, b = 4;
a = [a, b];
b = a[0];
a = a[1];
Enogwe Victor
sumber
1

Hingga ES5, untuk menukar dua angka, Anda harus membuat variabel temp dan kemudian menukarnya. Tetapi dalam ES6, sangat mudah untuk menukar dua angka menggunakan array yang merusak. Lihat contoh.

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
Avinash Malhotra
sumber
1

Karena saya mendengar metode ini berjalan lebih lambat:

b = [a, a = b][0];

Jika Anda berencana menyimpan vars di objek (atau larik), fungsi ini akan berfungsi:

function swapVars(obj, var1, var2){
    let temp = obj[var1];
    obj[var1] = obj[var2];
    obj[var2] = temp;
}

Pemakaian:

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'}
SwiftNinjaPro
sumber
1

Kita dapat menggunakan IIFE untuk menukar dua nilai tanpa parameter tambahan

var a = 5, b =8;
b = (function(a){ 
    return a 
}(a, a=b));

document.write("a: " + a+ "  b:  "+ b);

Ganesh Phirke
sumber
1

Destrukturisasi array ES6 digunakan untuk menukar dua variabel. Lihat contoh

var [x,y]=[1,2];
[x,y]=[y,x];

Cara yang lebih mudah dengan:

x === 1dan y === 2; Tapi setelah destructuring, xadalah y, yaitu 2, dan yini x, yaitu 1.

Krish Malhotra
sumber
1

Tukar menggunakan Bitwise

let a = 10;
let b = 20;
a ^= b;
y ^= a;
a ^= b;

Swap baris tunggal "menggunakan Array"

[a, b] = [b, a]
HusseiELbadady
sumber
-5

(fungsi (A, B) {b = A; a = B;}) (parseInt (a), parseInt (b));

Carlos Correia
sumber