Respostas:
Você só precisa de uma variável temporária.
var b = list[y];
list[y] = list[x];
list[x] = b;
Edite a resposta principal do seqüestro 10 anos depois com muita adoção do ES6 em nossos cintos:
Dada a matriz arr = [1,2,3,4]
, você pode trocar valores em uma linha agora da seguinte forma:
[arr[0], arr[1]] = [arr[1], arr[0]];
Isso produziria a matriz [2,1,3,4]
. Esta é uma tarefa de desestruturação .
[ list[y], list[x] ] = [ list[x], list[y] ];
[arr[0], arr[1]] = [arr[1], arr[0]]
produzir apenas [2, 1]
, sem o resto da matriz
Se você deseja uma única expressão, usando javascript nativo, lembre-se de que o valor de retorno de uma operação de emenda contém os elementos que foram removidos.
var A = [1, 2, 3, 4, 5, 6, 7, 8, 9], x= 0, y= 1;
A[x] = A.splice(y, 1, A[x])[0];
alert(A); // alerts "2,1,3,4,5,6,7,8,9"
Editar:
O [0]
é necessário no final da expressão, pois Array.splice()
retorna uma matriz e, nessa situação, exigimos o elemento único na matriz retornada.
Isso parece ok ....
var b = list[y];
list[y] = list[x];
list[x] = b;
Howerver usando
var b = list[y];
significa a b variável estará presente no restante do escopo. Isso pode levar a um vazamento de memória. Improvável, mas ainda melhor evitar.
Talvez seja uma boa ideia colocar isso em Array.prototype.swap
Array.prototype.swap = function (x,y) {
var b = this[x];
this[x] = this[y];
this[y] = b;
return this;
}
que pode ser chamado como:
list.swap( x, y )
Essa é uma abordagem limpa para evitar vazamentos de memória e DRY .
Array.prototype.swap = function (x,y) { if (x >= 0 && x < this.length && y >= 0 && y < this.length) { var b = this[x]; this[x] = this[y]; this[y] = b; } return this; };
De acordo com uma pessoa aleatória no Metafilter , "As versões recentes do Javascript permitem fazer trocas (entre outras coisas) de maneira muito mais clara:"
[ list[x], list[y] ] = [ list[y], list[x] ];
Meus testes rápidos mostraram que esse código Pythonic funciona muito bem na versão do JavaScript atualmente usada no "Script do Google Apps" (".gs"). Infelizmente, testes adicionais mostram que esse código fornece um "Erro de referência não detectado: lado esquerdo inválido na atribuição". em qualquer versão do JavaScript (".js") usada pelo Google Chrome versão 24.0.1312.57 m.
Bem, você não precisa armazenar os dois valores em buffer - apenas um:
var tmp = list[x];
list[x] = list[y];
list[y] = tmp;
Você pode trocar elementos em uma matriz da seguinte maneira:
list[x] = [list[y],list[y]=list[x]][0]
Veja o seguinte exemplo:
list = [1,2,3,4,5]
list[1] = [list[3],list[3]=list[1]][0]
//list is now [1,4,3,2,5]
Nota: funciona da mesma maneira para variáveis regulares
var a=1,b=5;
a = [b,b=a][0]
[list[x], list[y]] = [list[y], list[x]];
.
this[0] > this[1] && (this[0] = [this[1],this[1]=this[0]][0]);
Com valores numéricos, você pode evitar uma variável temporária usando xor bit a bit
list[x] = list[x] ^ list[y];
list[y] = list[y] ^ list[x];
list[x] = list[x] ^ list[y];
ou uma soma aritmética (observando que isso só funciona se x + y for menor que o valor máximo para o tipo de dados)
list[x] = list[x] + list[y];
list[y] = list[x] - list[y];
list[x] = list[x] - list[y];
list[y] = list[x] - list[x];
equivale apenas a list[y] = 0;
?
Isso não existia quando a pergunta foi feita, mas o ES2015 introduziu a desestruturação da matriz, permitindo que você a escreva da seguinte maneira:
let a = 1, b = 2;
// a: 1, b: 2
[a, b] = [b, a];
// a: 2, b: 1
[list[x], list[y]] = [list[y], list[x]];
Para trocar dois elementos consecutivos da matriz
array.splice(IndexToSwap,2,array[IndexToSwap+1],array[IndexToSwap]);
Resumo de http://www.greywyvern.com/?post=265
var a = 5, b = 9;
b = (a += b -= a) - b;
alert([a, b]); // alerts "9, 5"
swap(a, b)
função, não precisará se preocupar com a legibilidade.
o que dizer de Destructuring_assignment
var arr = [1, 2, 3, 4]
[arr[index1], arr[index2]] = [arr[index2], arr[index1]]
que também pode ser estendido para
[src order elements] => [dest order elements]
Considere essa solução sem a necessidade de definir a terceira variável:
function swap(arr, from, to) {
arr.splice(from, 1, arr.splice(to, 1, arr[from])[0]);
}
var letters = ["a", "b", "c", "d", "e", "f"];
swap(letters, 1, 4);
console.log(letters); // ["a", "e", "c", "d", "b", "f"]
Nota: convém adicionar verificações adicionais, por exemplo, para o comprimento da matriz. Esta solução é mutável, portanto, a swap
função não precisa retornar uma nova matriz, apenas faz a mutação na matriz passada.
arr.splice(from, 1, arr.splice(to, 1, ...arr[from]))
Você pode trocar qualquer número de objetos ou literais, mesmo de tipos diferentes, usando uma função de identidade simples como esta:
var swap = function (x){return x};
b = swap(a, a=b);
c = swap(a, a=b, b=c);
Para o seu problema:
var swap = function (x){return x};
list[y] = swap(list[x], list[x]=list[y]);
Isso funciona no JavaScript porque aceita argumentos adicionais, mesmo que não sejam declarados ou usados. As atribuições a=b
etc acontecem depois que a
são passadas para a função.
list[y] = (function(x){return x})(list[x],list[x]=list[y]);
. Ou, se você estiver interessado em ES6 (próxima versão do JS), é insanamente fácil: [list[x], list[y]] = [list[y], list[x]
. Estou tão feliz que eles estão adicionando alguns aspectos mais funcionais e baseados em classe na próxima versão do JavaScript.
[list[y], list[x]] = [list[x], list[y]];
Nenhuma variável temporária é necessária!
Eu estava pensando em simplesmente ligar list.reverse()
.
Mas então percebi que só funcionaria como swap quando list.length = x + y + 1
.
Analisei várias construções Javascript modernas para esse efeito, incluindo Mapa e mapa , mas infelizmente nenhuma resultou em um código mais compacto ou mais rápido do que essa construção antiquada e baseada em loop:
function multiswap(arr,i0,i1) {/* argument immutable if string */
if (arr.split) return multiswap(arr.split(""), i0, i1).join("");
var diff = [];
for (let i in i0) diff[i0[i]] = arr[i1[i]];
return Object.assign(arr,diff);
}
Example:
var alphabet = "abcdefghijklmnopqrstuvwxyz";
var [x,y,z] = [14,6,15];
var output = document.getElementsByTagName("code");
output[0].innerHTML = alphabet;
output[1].innerHTML = multiswap(alphabet, [0,25], [25,0]);
output[2].innerHTML = multiswap(alphabet, [0,25,z,1,y,x], [25,0,x,y,z,3]);
<table>
<tr><td>Input:</td> <td><code></code></td></tr>
<tr><td>Swap two elements:</td> <td><code></code></td></tr>
<tr><td>Swap multiple elements: </td> <td><code></code></td></tr>
</table>
var a = [1,2,3,4,5], b=a.length;
for (var i=0; i<b; i++) {
a.unshift(a.splice(1+i,1).shift());
}
a.shift();
//a = [5,4,3,2,1];
Aqui está uma versão compacta que troca o valor em i1 com i2 em arr
arr.slice(0,i1).concat(arr[i2],arr.slice(i1+1,i2),arr[i1],arr.slice(i2+1))
Aqui está uma variação que primeiro verifica se o índice existe na matriz:
Array.prototype.swapItems = function(a, b){
if( !(a in this) || !(b in this) )
return this;
this[a] = this.splice(b, 1, this[a])[0];
return this;
}
Atualmente, ele retornará apenas this
se o índice não existir, mas você poderá modificar facilmente o comportamento em caso de falha
Apenas por diversão, outra maneira sem usar nenhuma variável extra seria:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// swap index 0 and 2
arr[arr.length] = arr[0]; // copy idx1 to the end of the array
arr[0] = arr[2]; // copy idx2 to idx1
arr[2] = arr[arr.length-1]; // copy idx1 to idx2
arr.length--; // remove idx1 (was added to the end of the array)
console.log( arr ); // -> [3, 2, 1, 4, 5, 6, 7, 8, 9]
Por uma questão de brevidade, aqui está a versão feia de uma linha que é apenas um pouco menos feia do que todas as concat e fatias acima. A resposta aceita é realmente o caminho a percorrer e muito mais legível.
Dado:
var foo = [ 0, 1, 2, 3, 4, 5, 6 ];
se você deseja trocar os valores de dois índices (a e b); então isso faria isso:
foo.splice( a, 1, foo.splice(b,1,foo[a])[0] );
Por exemplo, se você deseja trocar os 3 e 5, pode fazê-lo desta maneira:
foo.splice( 3, 1, foo.splice(5,1,foo[3])[0] );
ou
foo.splice( 5, 1, foo.splice(3,1,foo[5])[0] );
Ambos produzem o mesmo resultado:
console.log( foo );
// => [ 0, 1, 2, 5, 4, 3, 6 ]
#splicehatersarepunks :)
Se você não deseja usar a variável temp no ES5, essa é uma maneira de trocar elementos da matriz.
var swapArrayElements = function (a, x, y) {
if (a.length === 1) return a;
a.splice(y, 1, a.splice(x, 1, a[y])[0]);
return a;
};
swapArrayElements([1, 2, 3, 4, 5], 1, 3); //=> [ 1, 4, 3, 2, 5 ]
a.splice
retorna uma matriz com os elementos removidos. developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
tente esta função ...
$(document).ready(function () {
var pair = [];
var destinationarray = ['AAA','BBB','CCC'];
var cityItems = getCityList(destinationarray);
for (var i = 0; i < cityItems.length; i++) {
pair = [];
var ending_point = "";
for (var j = 0; j < cityItems[i].length; j++) {
pair.push(cityItems[i][j]);
}
alert(pair);
console.log(pair)
}
});
function getCityList(inputArray) {
var Util = function () {
};
Util.getPermuts = function (array, start, output) {
if (start >= array.length) {
var arr = array.slice(0);
output.push(arr);
} else {
var i;
for (i = start; i < array.length; ++i) {
Util.swap(array, start, i);
Util.getPermuts(array, start + 1, output);
Util.swap(array, start, i);
}
}
}
Util.getAllPossiblePermuts = function (array, output) {
Util.getPermuts(array, 0, output);
}
Util.swap = function (array, from, to) {
var tmp = array[from];
array[from] = array[to];
array[to] = tmp;
}
var output = [];
Util.getAllPossiblePermuts(inputArray, output);
return output;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
var arr = [1, 2];
arr.splice(0, 2, arr[1], arr[0]);
console.log(arr); //[2, 1]
Usando o ES6 , é possível fazer assim ...
Imagine que você tem essas duas matrizes ...
const a = ["a", "b", "c", "d", "e"];
const b = [5, 4, 3, 2, 1];
e você deseja trocar os primeiros valores:
const [a0] = a;
a[0] = b[0];
b[0] = a0;
e valor:
a; //[5, "b", "c", "d", "e"]
b; //["a", 4, 3, 2, 1]
Array.prototype.swap = function(a, b) {
var temp = this[a];
this[a] = this[b];
this[b] = temp;
};
Uso:
var myArray = [0,1,2,3,4...];
myArray.swap(4,1);
Array
protótipo não fazia parte do que foi solicitado - ele pode confundir mais do que serve.
Se for necessário trocar apenas o primeiro e o último elementos:
array.unshift( array.pop() );
[1, 2, 3] => [3, 1, 2]
vez de [1, 2, 3] => [3, 2, 1]
.
a = [b, b = a][0];
como apontado por @Jan Embora eu ainda me encontre utilizando a abordagem de variável temporária como é uma linguagem cruzada (por exemplo, C / C ++ ) e a primeira abordagem que geralmente vem à minha mente.