Esiste un modo più semplice per scambiare due elementi in un array?
var a = list[x], b = list[y];
list[y] = a;
list[x] = b;
Esiste un modo più semplice per scambiare due elementi in un array?
var a = list[x], b = list[y];
list[y] = a;
list[x] = b;
Risposte:
Hai solo bisogno di una variabile temporanea.
var b = list[y];
list[y] = list[x];
list[x] = b;
Modifica la risposta principale del dirottamento 10 anni dopo con molta adozione di ES6 sotto le nostre cinture:
Dato l'array arr = [1,2,3,4]
, ora puoi scambiare i valori in una riga in questo modo:
[arr[0], arr[1]] = [arr[1], arr[0]];
Ciò produrrebbe l'array [2,1,3,4]
. Questo è un compito distruttivo .
[ list[y], list[x] ] = [ list[x], list[y] ];
[arr[0], arr[1]] = [arr[1], arr[0]]
produce solo [2, 1]
senza il resto dell'array
Se si desidera una singola espressione, utilizzando JavaScript nativo, ricordare che il valore restituito da un'operazione di giunzione contiene gli elementi che sono stati rimossi.
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"
Modificare:
Il [0]
occorre alla fine dell'espressione quale Array.splice()
restituisce una matrice, e in questa situazione si richiedono singolo elemento nell'array restituito.
Questo sembra ok ....
var b = list[y];
list[y] = list[x];
list[x] = b;
Uso di Howerver
var b = list[y];
significa che una variabile b sarà presente per il resto dell'ambito. Ciò può potenzialmente causare una perdita di memoria. Improbabile, ma ancora meglio da evitare.
Forse è una buona idea metterlo in Array.prototype.swap
Array.prototype.swap = function (x,y) {
var b = this[x];
this[x] = this[y];
this[y] = b;
return this;
}
che può essere chiamato come:
list.swap( x, y )
Questo è un approccio pulito sia per evitare perdite di memoria che a SECCO .
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; };
Secondo una persona a caso su Metafilter , "Le versioni recenti di Javascript ti consentono di fare scambi (tra le altre cose) molto più ordinatamente:"
[ list[x], list[y] ] = [ list[y], list[x] ];
I miei test rapidi hanno dimostrato che questo codice Pythonic funziona alla grande nella versione di JavaScript attualmente utilizzata in "Google Apps Script" (".gs"). Purtroppo, ulteriori test mostrano che questo codice fornisce un "Errore di riferimento non rilevato: lato sinistro non valido nell'assegnazione." in qualunque versione di JavaScript (".js") è utilizzata da Google Chrome versione 24.0.1312.57 m.
Bene, non è necessario bufferizzare entrambi i valori - solo uno:
var tmp = list[x];
list[x] = list[y];
list[y] = tmp;
È possibile scambiare elementi in un array nel modo seguente:
list[x] = [list[y],list[y]=list[x]][0]
Vedi il seguente esempio:
list = [1,2,3,4,5]
list[1] = [list[3],list[3]=list[1]][0]
//list is now [1,4,3,2,5]
Nota: funziona allo stesso modo per le variabili regolari
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]);
Con valori numerici puoi evitare una variabile temporanea usando xor bit a bit
list[x] = list[x] ^ list[y];
list[y] = list[y] ^ list[x];
list[x] = list[x] ^ list[y];
o una somma aritmetica (osservando che funziona solo se x + y è inferiore al valore massimo per il tipo di dati)
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 a list[y] = 0;
?
Questo non esisteva quando veniva posta la domanda, ma ES2015 introdusse l'array destructuring, permettendoti di scriverlo come segue:
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]];
Per scambiare due elementi consecutivi di matrice
array.splice(IndexToSwap,2,array[IndexToSwap+1],array[IndexToSwap]);
Digest da 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)
funzione non devi preoccuparti della leggibilità.
che dire di Destructuring_assignment
var arr = [1, 2, 3, 4]
[arr[index1], arr[index2]] = [arr[index2], arr[index1]]
che può anche essere esteso a
[src order elements] => [dest order elements]
Considera una soluzione del genere senza la necessità di definire la terza variabile:
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: è possibile che si desideri aggiungere ulteriori controlli, ad esempio per la lunghezza dell'array. Questa soluzione è mutabile, quindi la swap
funzione non ha bisogno di restituire un nuovo array, ma fa solo una mutazione sull'array passato.
arr.splice(from, 1, arr.splice(to, 1, ...arr[from]))
Puoi scambiare qualsiasi numero di oggetti o letterali, anche di tipi diversi, usando una semplice funzione di identità come questa:
var swap = function (x){return x};
b = swap(a, a=b);
c = swap(a, a=b, b=c);
Per il tuo problema:
var swap = function (x){return x};
list[y] = swap(list[x], list[x]=list[y]);
Funziona in JavaScript perché accetta argomenti aggiuntivi anche se non vengono dichiarati o utilizzati. Le assegnazioni a=b
ecc. Si verificano dopo che a
è stato passato alla funzione.
list[y] = (function(x){return x})(list[x],list[x]=list[y]);
. Oppure, se siete interessati a ES6 (prossima versione di JS), è incredibilmente facile: [list[x], list[y]] = [list[y], list[x]
. Sono così felice che stiano aggiungendo alcuni aspetti più funzionali e di classe nella prossima versione di JavaScript.
[list[y], list[x]] = [list[x], list[y]];
Nessuna variabile temporanea richiesta!
Stavo pensando di chiamare semplicemente list.reverse()
.
Ma poi ho capito che avrebbe funzionato come swap solo quandolist.length = x + y + 1
.
Ho esaminato varie costruzioni Javascript moderne in questo senso, tra cui Map e map , ma purtroppo nessuna ha portato a un codice più compatto o più veloce di questa costruzione vecchio stile basata su 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];
Ecco una versione compatta scambia valore a i1 con i2 in arr
arr.slice(0,i1).concat(arr[i2],arr.slice(i1+1,i2),arr[i1],arr.slice(i2+1))
Ecco una variante che controlla innanzitutto se l'indice esiste nell'array:
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;
}
Al momento restituirà solo this
se l'indice non esiste, ma è possibile modificare facilmente il comportamento in caso di errore
Soluzione dattiloscritta che clona l'array invece di mutare quello esistente
export function swapItemsInArray<T>(items: T[], indexA: number, indexB: number): T[] {
const itemA = items[indexA];
const clone = [...items];
clone[indexA] = clone[indexB];
clone[indexB] = itemA;
return clone;
}
Solo per divertirci, un altro modo senza usare alcuna variabile aggiuntiva sarebbe:
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]
Per brevità, ecco la brutta versione da 1 linea che è solo leggermente meno brutta di tutto ciò che si concatena e affetta sopra. La risposta accettata è davvero la strada da percorrere e molto più leggibile.
Dato:
var foo = [ 0, 1, 2, 3, 4, 5, 6 ];
se si desidera scambiare i valori di due indici (a e b); allora questo lo farebbe:
foo.splice( a, 1, foo.splice(b,1,foo[a])[0] );
Ad esempio, se si desidera scambiare 3 e 5, è possibile farlo in questo modo:
foo.splice( 3, 1, foo.splice(5,1,foo[3])[0] );
o
foo.splice( 5, 1, foo.splice(3,1,foo[5])[0] );
Entrambi producono lo stesso risultato:
console.log( foo );
// => [ 0, 1, 2, 5, 4, 3, 6 ]
#splicehatersarepunks :)
Se non si desidera utilizzare la variabile temp in ES5, questo è un modo per scambiare elementi dell'array.
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
restituisce un array con gli elementi rimossi. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
prova questa funzione ...
$(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]
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
prototipo non faceva parte di ciò che era stato chiesto: potrebbe confondere più di quanto non faccia bene.
Se necessario, scambiare solo il primo e l'ultimo elemento:
array.unshift( array.pop() );
[1, 2, 3] => [3, 1, 2]
invece di [1, 2, 3] => [3, 2, 1]
.
a = [b, b = a][0];
come sottolineato da @Jan Anche se mi trovo ancora a utilizzare l'approccio variabile temporaneo in quanto è linguistico (ad esempio C / C ++ ) e il primo approccio che di solito mi viene in mente.