มีวิธีที่ง่ายกว่าในการสลับสององค์ประกอบในอาร์เรย์หรือไม่?
var a = list[x], b = list[y];
list[y] = a;
list[x] = b;
มีวิธีที่ง่ายกว่าในการสลับสององค์ประกอบในอาร์เรย์หรือไม่?
var a = list[x], b = list[y];
list[y] = a;
list[x] = b;
คำตอบ:
คุณต้องการเพียงหนึ่งตัวแปรชั่วคราว
var b = list[y];
list[y] = list[x];
list[x] = b;
แก้ไขการไฮแจ็คคำตอบยอดนิยม 10 ปีต่อมาด้วยการนำ ES6 มาใช้อย่างมากมายภายใต้สายรัดของเรา:
รับอาร์เรย์arr = [1,2,3,4]
คุณสามารถสลับค่าในหนึ่งบรรทัดตอนนี้เช่น:
[arr[0], arr[1]] = [arr[1], arr[0]];
[2,1,3,4]
นี้จะผลิตอาร์เรย์ นี่คือการกำหนด destructuring
[ list[y], list[x] ] = [ list[x], list[y] ];
[arr[0], arr[1]] = [arr[1], arr[0]]
ผลิตเฉพาะ[2, 1]
โดยไม่ต้องมีส่วนที่เหลือของอาร์เรย์
หากคุณต้องการนิพจน์เดียวใช้จาวาสคริปต์ดั้งเดิมโปรดจำไว้ว่าค่าส่งคืนจากการดำเนินการประกบกันมีองค์ประกอบที่ถูกลบออก
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"
แก้ไข:
[0]
เป็นสิ่งจำเป็นในตอนท้ายของการแสดงออกเป็นArray.splice()
ผลตอบแทนอาร์เรย์และในสถานการณ์เช่นนี้เราจำเป็นต้องมีองค์ประกอบเดียวในอาร์เรย์กลับ
ดูเหมือนว่าจะโอเค ....
var b = list[y];
list[y] = list[x];
list[x] = b;
ใช้ Howerver
var b = list[y];
หมายความว่าตัวแปรbจะมีอยู่ในส่วนที่เหลือของขอบเขต สิ่งนี้อาจนำไปสู่การรั่วไหลของหน่วยความจำ ไม่น่าจะ แต่ก็ยังดีกว่าที่จะหลีกเลี่ยง
อาจเป็นความคิดที่ดีที่จะใส่สิ่งนี้ลงใน Array.prototype.swap
Array.prototype.swap = function (x,y) {
var b = this[x];
this[x] = this[y];
this[y] = b;
return this;
}
ซึ่งสามารถเรียกเช่น:
list.swap( x, y )
นี้เป็นวิธีการทำความสะอาดทั้งหลีกเลี่ยงการรั่วไหลของหน่วยความจำและแห้ง
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; };
จากการสุ่มของเมตาฟิลเทอร์บางคน "จาวาสคริปต์เวอร์ชันล่าสุดอนุญาตให้คุณทำการแลกเปลี่ยน (เหนือสิ่งอื่นใด) ได้อย่างเรียบร้อยยิ่งขึ้น:"
[ list[x], list[y] ] = [ list[y], list[x] ];
การทดสอบอย่างรวดเร็วของฉันแสดงให้เห็นว่ารหัส Pythonicนี้ใช้งานได้ดีในเวอร์ชันของ JavaScript ที่ใช้ในปัจจุบัน "สคริปต์ Google Apps" (".gs") อนิจจาการทดสอบเพิ่มเติมแสดงรหัสนี้ให้ "Uncaught ReferenceError: ไม่ถูกต้องด้านซ้ายมือในการกำหนด" Google Chrome เวอร์ชันใดก็ตามที่ใช้ JavaScript (".js") 24.0.1312.57 m
คุณไม่จำเป็นต้องบัฟเฟอร์ทั้งสองค่า - เพียงค่าเดียว:
var tmp = list[x];
list[x] = list[y];
list[y] = tmp;
คุณสามารถสลับองค์ประกอบในอาร์เรย์ด้วยวิธีต่อไปนี้:
list[x] = [list[y],list[y]=list[x]][0]
ดูตัวอย่างต่อไปนี้:
list = [1,2,3,4,5]
list[1] = [list[3],list[3]=list[1]][0]
//list is now [1,4,3,2,5]
หมายเหตุ: มันทำงานในลักษณะเดียวกันกับตัวแปรปกติ
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]);
ด้วยค่าตัวเลขคุณสามารถหลีกเลี่ยงตัวแปรชั่วคราวได้โดยใช้ bitwise xor
list[x] = list[x] ^ list[y];
list[y] = list[y] ^ list[x];
list[x] = list[x] ^ list[y];
หรือผลรวมเลขคณิต (การสังเกตว่าวิธีนี้ใช้ได้เฉพาะเมื่อ x + y น้อยกว่าค่าสูงสุดสำหรับประเภทข้อมูล)
list[x] = list[x] + list[y];
list[y] = list[x] - list[y];
list[x] = list[x] - list[y];
list[y] = list[x] - list[x];
เพียงถือเอาlist[y] = 0;
ใช่หรือไม่
สิ่งนี้ไม่มีอยู่เมื่อมีการถามคำถาม แต่ ES2015 แนะนำการทำลายอาร์เรย์ซึ่งช่วยให้คุณสามารถเขียนได้ดังนี้:
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]];
เพื่อสลับสององค์ประกอบต่อเนื่องของอาร์เรย์
array.splice(IndexToSwap,2,array[IndexToSwap+1],array[IndexToSwap]);
สรุปโดยย่อจาก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)
ฟังก์ชั่นคุณไม่จำเป็นต้องกังวลเกี่ยวกับความสามารถในการอ่าน
สิ่งที่เกี่ยวกับDestructuring_assignment
var arr = [1, 2, 3, 4]
[arr[index1], arr[index2]] = [arr[index2], arr[index1]]
ซึ่งสามารถขยายไปถึง
[src order elements] => [dest order elements]
พิจารณาโซลูชันดังกล่าวโดยไม่จำเป็นต้องกำหนดตัวแปรที่สาม:
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"]
หมายเหตุ: คุณอาจต้องการเพิ่มการตรวจสอบเพิ่มเติมเช่นความยาวของอาร์เรย์ โซลูชันนี้ไม่แน่นอนดังนั้นswap
ฟังก์ชั่นไม่จำเป็นต้องส่งคืนอาเรย์ใหม่มันแค่ทำการเปลี่ยนรูปไปที่อาเรย์ที่ถูกส่งเข้ามา
arr.splice(from, 1, arr.splice(to, 1, ...arr[from]))
คุณสามารถสลับวัตถุหรือตัวอักษรจำนวนเท่าใดก็ได้แม้จะเป็นชนิดต่าง ๆ โดยใช้ฟังก์ชั่นระบุตัวตนแบบง่าย ๆ ดังนี้:
var swap = function (x){return x};
b = swap(a, a=b);
c = swap(a, a=b, b=c);
สำหรับปัญหาของคุณ:
var swap = function (x){return x};
list[y] = swap(list[x], list[x]=list[y]);
สิ่งนี้ใช้ได้ใน JavaScript เพราะยอมรับข้อโต้แย้งเพิ่มเติมแม้ว่าจะไม่ได้ประกาศหรือใช้ก็ตาม การมอบหมายa=b
ฯลฯ เกิดขึ้นหลังจากa
ถูกส่งผ่านเข้าไปในฟังก์ชัน
list[y] = (function(x){return x})(list[x],list[x]=list[y]);
แต่คุณสามารถทำอย่างใดอย่างหนึ่งที่ดีกว่าถ้าคุณเป็นเพียงการใช้ฟังก์ชั่นเมื่อ: หรือถ้าคุณสนใจใน ES6 (รุ่นถัดไปของ JS) [list[x], list[y]] = [list[y], list[x]
ก็เมามันง่าย: ฉันดีใจที่พวกเขาเพิ่มการทำงานและการใช้งานคลาสเพิ่มเติมลงใน JavaScript เวอร์ชันถัดไป
[list[y], list[x]] = [list[x], list[y]];
ไม่ต้องใช้ตัวแปรชั่วคราว!
list.reverse()
ฉันคิดเกี่ยวกับเพียงแค่โทร แต่แล้วฉันรู้ว่ามันจะทำงานตามที่แลกเปลี่ยนเฉพาะเมื่อ
list.length = x + y + 1
ฉันได้ดูโครงสร้าง Javascript ที่ทันสมัยหลายอย่างเกี่ยวกับเอฟเฟกต์นี้รวมถึงแผนที่และแผนที่แต่น่าเสียดายที่ไม่มีใครทำโค้ดที่กะทัดรัดหรือเร็วกว่าโครงสร้างแบบลูปที่ล้าสมัยนี้:
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;
var b = 2;
[a,b] = [b,a];
(วิธี ES6)
var a= [7,8,9,10], i=2, j=3;[a[i],a[j]] = [a[j],a[i]];
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];
นี่คือสายการบินหนึ่งที่ไม่ได้กลายพันธุ์list
:
let newList = Object.assign([], list, {[x]: list[y], [y]: list[x]})
(ใช้คุณสมบัติภาษาไม่พร้อมใช้งานในปี 2009 เมื่อมีการโพสต์คำถาม!)
ต่อไปนี้เป็นค่าเวอร์ชั่นสลับขนาดกะทัดรัดที่ i1 กับ i2 ใน arr
arr.slice(0,i1).concat(arr[i2],arr.slice(i1+1,i2),arr[i1],arr.slice(i2+1))
นี่คือรูปแบบที่ตรวจสอบก่อนว่าดัชนีมีอยู่ในอาร์เรย์หรือไม่:
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;
}
ปัจจุบันมันจะกลับมาthis
หากไม่มีดัชนี แต่คุณสามารถปรับเปลี่ยนพฤติกรรมที่ล้มเหลวได้อย่างง่ายดาย
สลับองค์ประกอบแรกและสุดท้ายในอาร์เรย์โดยไม่มีตัวแปรชั่วคราวหรือวิธีการแลกเปลี่ยน ES6 [a, b] = [b, a]
[a.pop(), ...a.slice(1), a.shift()]
โซลูชั่น typescript ที่โคลนอาร์เรย์แทนการกลายพันธุ์ที่มีอยู่
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;
}
เพียงเพื่อความสนุกของมันวิธีอื่นโดยไม่ใช้ตัวแปรพิเศษใด ๆ จะเป็น:
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]
เพื่อความสั้นกระชับนี่เป็นเวอร์ชั่นซับน่าเกลียดที่มีความน่าเกลียดน้อยกว่า concat และการกรีดด้านบนเล็กน้อย คำตอบที่ได้รับการยอมรับเป็นวิธีที่จะไปอย่างแท้จริงและสามารถอ่านได้มากขึ้น
ได้รับ:
var foo = [ 0, 1, 2, 3, 4, 5, 6 ];
หากคุณต้องการสลับค่าของสองดัชนี (a และ b); แล้วสิ่งนี้จะทำ:
foo.splice( a, 1, foo.splice(b,1,foo[a])[0] );
ตัวอย่างเช่นหากคุณต้องการสลับ 3 และ 5 คุณสามารถทำได้ด้วยวิธีนี้:
foo.splice( 3, 1, foo.splice(5,1,foo[3])[0] );
หรือ
foo.splice( 5, 1, foo.splice(3,1,foo[5])[0] );
ทั้งคู่ให้ผลลัพธ์เหมือนกัน:
console.log( foo );
// => [ 0, 1, 2, 5, 4, 3, 6 ]
#splicehatersarepunks :)
หากคุณไม่ต้องการใช้ตัวแปร temp ใน ES5 นี่เป็นวิธีหนึ่งในการสลับองค์ประกอบอาร์เรย์
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
ส่งคืนอาร์เรย์ที่มีองค์ประกอบที่ถูกลบ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
ลองฟังก์ชั่นนี้ ...
$(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]
การใช้ES6เป็นไปได้ที่จะทำเช่นนี้ ...
ลองนึกภาพคุณมี2 อาร์เรย์เหล่านี้...
const a = ["a", "b", "c", "d", "e"];
const b = [5, 4, 3, 2, 1];
และคุณต้องการสลับค่าแรก:
const [a0] = a;
a[0] = b[0];
b[0] = a0;
และความคุ้มค่า:
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;
};
การใช้งาน:
var myArray = [0,1,2,3,4...];
myArray.swap(4,1);
Array
ต้นแบบไม่ได้เป็นส่วนหนึ่งของสิ่งที่ขอ - มันอาจสร้างความสับสนได้มากกว่าสิ่งที่ดี
หากต้องการสลับองค์ประกอบแรกและสุดท้ายเท่านั้น:
array.unshift( array.pop() );
[1, 2, 3] => [3, 1, 2]
[1, 2, 3] => [3, 2, 1]
a = [b, b = a][0];
ตามที่ @Jan ชี้ให้เห็นแม้ว่าฉันยังพบว่าตัวเองใช้วิธีการตัวแปรชั่วคราวเช่นข้ามภาษา (เช่น C / C ++ ) และวิธีการแรกที่มักจะปรากฏในใจของฉัน