Thông thường, hoán đổi giá trị của hai biến cần 3 câu lệnh và 1 biến phụ. Bạn có ngạc nhiên không nếu tôi bảo rằng: trong JavaScript (JS), còn có cách đơn giản hơn như thế nhiều.
Có hai loại hoán đổi. Loại thứ nhất, tạm gọi là loại cổ điển, đó là khi chúng ta hoán đổi hai số cho nhau. Loại thứ hai phức tạp hơn: hoán đổi hai biến có kiểu dữ liệu bất kì (string, float, object, v.v…)
----
Mục tiêu: hoán đổi giá trị của 2 biến a và b (kiểu bất kỳ).
----
Đối với số nguyên
Bắt đầu với thử thách đầu tiên: số nguyên
DÙNG TOÁN TỬ TOÁN HỌC
Bởi đây là các số nguyên, chúng ta có thể khéo léo dùng toán tử đảo bit là XOR trong trường hợp này:
VÀI MẸO HAY HO KHÁC
Hoán đổi trong một dòng
(ND: Nếu hoán đổi hai biến kiểu string, chỉ cần thay đổi số 0 thành “”).
Nó chạy cụ thể như sau:
Lời giải dùng được với MỌI KIỂU DỮ LIỆU
Nhiệm vụ thứ hai khó nhai hơn: đổi giá trị 2 biến bất kỳ
PHƯƠNG PHÁP CỔ ĐIỂN TRONG MỘT DÒNG LỆNH
Mẹo này sử dụng mảng để hoán đổi biến. Đọc qua dòng lệnh và thử suy nghĩ chút nhé:
PHƯƠNG PHÁP HOÁN ĐỔI KHÁC
Với ES6, ta có thể dùng hàm rút gọn:
PHƯƠNG PHÁP DÙNG CHO ES6 TRỞ LÊN
Kể từ ES6, bạn đã có thể hoán đổi hai biến một cách đẹp trai hơn. Chỉ đơn giản gán hai mảng như sau:
[Tác giả: Александр Майоров
Ngày xuất bản 18/06/2016
Link bài viết gốc: https://link.medium.com/A3lZ79skl4
Dịch: Bùi Thanh Lâm]
Có hai loại hoán đổi. Loại thứ nhất, tạm gọi là loại cổ điển, đó là khi chúng ta hoán đổi hai số cho nhau. Loại thứ hai phức tạp hơn: hoán đổi hai biến có kiểu dữ liệu bất kì (string, float, object, v.v…)
----
Mục tiêu: hoán đổi giá trị của 2 biến a và b (kiểu bất kỳ).
let a = 1,
b = 2,
c = 0;
c = a;
a = b;
Hiển nhiên, chúng ta thấy xuất hiện một biến mới, tạm lưu giá trị của a trong quá trình hoán đổi. Vậy không cần thằng c này có được không? Được, được chứ!b = c;
----
Đối với số nguyên
Bắt đầu với thử thách đầu tiên: số nguyên
DÙNG TOÁN TỬ TOÁN HỌC
a = a + b
b = a - b
Hoặc viết gọn là:a = a - b
a += b
b = a - b
DÙNG TOÁN TỬ XORa -= b
Bởi đây là các số nguyên, chúng ta có thể khéo léo dùng toán tử đảo bit là XOR trong trường hợp này:
a = a ^ b
b = a ^ b
Hoặc viết gọn là:a = a ^ b
a ^= b
b ^= a
Đây còn được gọi là Thuật toán hoán đổi dùng XOR. Nguyên lý của nó được mô tả trong bài viết sau (ND: click để xem – Wikipedia).a ^= b
VÀI MẸO HAY HO KHÁC
Hoán đổi trong một dòng
Phương án này không cần biến phụ, không dùng mảng, chỉ thêm thắt có một xíu vậy thôi, và nó chạy rất nhanh. Thực tế đôi khi nó còn nhanh hơn cách dùng biến phụ nếu chạy trên một vài nền tảng. Nó đúng với mọi loại số, không bao giờ tràn bộ nhớ, và cân luôn mấy trường hợp đặc biệt chẳng hạn Infinity hay NaN.a = b + (b=a, 0)
(ND: Nếu hoán đổi hai biến kiểu string, chỉ cần thay đổi số 0 thành “”).
Nó chạy cụ thể như sau:
- (b=a, 0): gán giá trị ban đầu của a cho b, trả về số 0. (ND: Bạn đọc nào chưa hiểu rõ cái này, xem thêm tài liệu tại đây).
- a = b + 0: gán giá trị b (ban đầu) + 0 cho a, tức gán a = b
Hoán đổi một dòng, dùng XORb=a+(a=b)-b
----a = a^b^(b^=(a^b))
Lời giải dùng được với MỌI KIỂU DỮ LIỆU
Nhiệm vụ thứ hai khó nhai hơn: đổi giá trị 2 biến bất kỳ
PHƯƠNG PHÁP CỔ ĐIỂN TRONG MỘT DÒNG LỆNH
Mẹo này sử dụng mảng để hoán đổi biến. Đọc qua dòng lệnh và thử suy nghĩ chút nhé:
Có vài điều đáng nói ở đây. Nếu bạn chưa hiểu câu lệnh này chạy thế nào, hãy đọc phần giải thích này:a = [b, b=a][0];
- Khởi tạo một mảng với phần tử đầu là b, phần tử số 2 là b
- Gán b = a ngay khi mảng được khởi tạo
- Gán giá trị của phần tử đầu tiên trong mảng, tức giá trị của b ban đầu, cho a.
PHƯƠNG PHÁP HOÁN ĐỔI KHÁC
Với ES6, ta có thể dùng hàm rút gọn:
Hoặc nếu trong ES5, câu lệnh này được viết là:b = (a=>a)(a,a=b);
(ND: Hàm dạng này gọi là self-executing function. Xem thêm tại đây)b = (function(a){ return a })(a,a=b);
PHƯƠNG PHÁP DÙNG CHO ES6 TRỞ LÊN
Kể từ ES6, bạn đã có thể hoán đổi hai biến một cách đẹp trai hơn. Chỉ đơn giản gán hai mảng như sau:
(ND: Đây là destructuring assignment, xem thêm tại đây)[a, b] = [b, a]
[Tác giả: Александр Майоров
Ngày xuất bản 18/06/2016
Link bài viết gốc: https://link.medium.com/A3lZ79skl4
Dịch: Bùi Thanh Lâm]