Відповіді:
Ось однолінійка для заміни значень двох змінних.
Дані змінні 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
помилку.
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). Усі, хто підтримує код (включаючи вас через півроку), точно знатимуть, що відбувається.
Оскільки це цілі числа, ви також можете використовувати будь-яку кількість розумних хитрощів 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);
Це називається алгоритмом swap XOR. Його теорія функціонування описана в цій статті Вікіпедії .
1 "Грамотний програміст повністю усвідомлює обмежений розмір власного черепа. Тому він підходить до своєї задачі з повним смиренням і уникає розумних хитрощів, як чума". - Едсгер В. Дійкстра
ToInt32
внутрішній метод - див. Розділ 11.10 стандарту ECMAScript ). Це не дає правильних результатів для не цілих числових значень. Він також перетворює нечислові значення в 32-бітні цілі числа. Якщо ви починаєте з a = "hi"
і b = "there"
, ви закінчуєте з a == 0
і b == 0
.
typeof a == 'boolean'
або a === false
, наприклад. Реальні числа працюють, за винятком того, що вони спрямовані на нуль проти округленого до найближчого цілого числа.
Не використовуйте наведений нижче код. Це не рекомендований спосіб замінювати значення двох змінних (просто використовуйте для цього тимчасову змінну ). Він просто показує хитрість JavaScript.
Це рішення не використовує жодних тимчасових змінних, без масивів, лише одне додавання, і це швидко . Насправді це іноді швидше, ніж тимчасова змінна на кількох платформах .
Він працює для всіх чисел, ніколи не переповнює і обробляє крайові випадки, такі як Infinity та NaN.
a = b + (b=a, 0)
Він працює в два етапи:
(b=a, 0)
встановлює b
старе значення a
і врожайність0
a = b + 0
встановлює a
старе значенняb
,
, і він був завернутий для встановлення права пріоритету. Оператор комами оцінює обидва свої аргументи (у даному випадку b=a
та 0
) та повертає останній (у цьому випадку 0
). Тож тут, це впливає на встановлення нового b
на старе значення a
, при цьому поступаючись 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;
Особистий смак.
Метод ES6 +: з ES6 ви можете міняти змінні більш елегантно. Ви можете використовувати зіставлення масиву присвоєння масиву. Це просто. var a = 10 b = 20;
[a, b] = [b, a]
console.log (a, b) // 20 10
Тепер ви можете нарешті зробити:
let a = 5;
let b = 10;
[a, b] = [b, a]; // ES6
console.log(a, b);
Ви можете використовувати тимчасову змінну swap або 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
Оскільки ваше запитання було дорогоцінним "Тільки ці змінні, а не будь-які об'єкти", відповідь буде також дорогоцінною:
var 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,_);
Останній розкриває глобальну змінну '_', але це не має значення, як типова умова javascript - використовувати її як змінну 'dont care'.
a = (_=b,b=a,_);
_
? Чому вона не потребує декларації?
Я бачу тут якусь програму олімпіади з програмування. Ще одне хитро однолінійне рішення:
b = (function(){ a=b; return arguments[0]; })(a);
arguments
, просто робіть b = (function (x){ return x; })(a, a=b)
.
arguments
список також буде змінною.
a
до arguments[0]
пропусканням його в якості параметра.
arguments
а його призначення відбувається "за лаштунками"
Заміна одного рядка
a = a^b^(b^=(a^b));
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 // або і та запустіть з одним набором коду
Ми можемо поміняти 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
let a = 2, b = 4;
[b, a] = [a, b];
більш детальним був би підхід
let a = 2, b = 4;
a = [a, b];
b = a[0];
a = a[1];
Це дуже просто, використовуйте синтаксис руйнування масиву ES6, який [y, x] = [x, y]
для отримання додаткової інформації див. За посиланням https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
До ES5, щоб поміняти місцями два числа, ви повинні створити змінну temp, а потім поміняти її. Але в ES6 дуже просто замінити два числа за допомогою деструктуризації масиву. Див. Приклад.
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];
Якщо ви плануєте зберігати ваші параметри в об'єкті (або масиві), ця функція повинна працювати:
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 для заміни двох значень без додаткових параметрів
var a = 5, b =8;
b = (function(a){
return a
}(a, a=b));
document.write("a: " + a+ " b: "+ b);
Руйнування масиву ES6 використовується для заміни двох змінних. Див. Приклад
var [x,y]=[1,2];
[x,y]=[y,x];
Простіший спосіб можливий за допомогою:
x === 1
і y === 2
; Але після руйнування x
є y
, тобто є 2
і y
є x
, тобто 1
.
Міняйте за допомогою побітових
let a = 10;
let b = 20;
a ^= b;
y ^= a;
a ^= b;
Однорядковий своп "за допомогою масиву"
[a, b] = [b, a]
(функція (A, B) {b = A; a = B;}) (parseInt (a), parseInt (b));