ฉันกำลังมองหาวิธีแทรกอาเรย์ JavaScript ในรูปแบบของ:
arr.insert(index, item)
โดยเฉพาะอย่างยิ่งใน jQuery แต่การใช้ JavaScript ใด ๆ จะทำในจุดนี้
ฉันกำลังมองหาวิธีแทรกอาเรย์ JavaScript ในรูปแบบของ:
arr.insert(index, item)
โดยเฉพาะอย่างยิ่งใน jQuery แต่การใช้ JavaScript ใด ๆ จะทำในจุดนี้
คำตอบ:
สิ่งที่คุณต้องการคือsplice
ฟังก์ชั่นบนวัตถุอาเรย์พื้นเมือง
arr.splice(index, 0, item);
จะแทรกitem
ลงarr
ในดัชนีที่ระบุ (การลบ0
รายการแรกนั่นคือเป็นเพียงการแทรก)
ในตัวอย่างนี้เราจะสร้างอาร์เรย์และเพิ่มองค์ประกอบลงในดัชนี 2:
var arr = [];
arr[0] = "Jani";
arr[1] = "Hege";
arr[2] = "Stale";
arr[3] = "Kai Jim";
arr[4] = "Borge";
console.log(arr.join());
arr.splice(2, 0, "Lene");
console.log(arr.join());
arr.splice(2,3)
จะลบ 3 องค์ประกอบเริ่มต้นที่ดัชนี 2 โดยไม่ผ่านพารามิเตอร์ที่ 3 .... ไม่มีการแทรกอะไรเลย ดังนั้นชื่อinsert()
ก็ไม่ยุติธรรมเช่นกัน
คุณสามารถใช้Array.insert
วิธีนี้ได้โดยทำสิ่งนี้:
Array.prototype.insert = function ( index, item ) {
this.splice( index, 0, item );
};
จากนั้นคุณสามารถใช้มันเช่น:
var arr = [ 'A', 'B', 'D', 'E' ];
arr.insert(2, 'C');
// => arr == [ 'A', 'B', 'C', 'D', 'E' ]
Array.prototype.insert = function (index, items) { this.splice.apply(this, [index, 0].concat(items)); }
นอกเหนือจากการประกบกันคุณสามารถใช้วิธีการนี้ซึ่งจะไม่กลายพันธุ์อาร์เรย์เดิม แต่จะสร้างอาร์เรย์ใหม่ด้วยรายการที่เพิ่ม คุณควรหลีกเลี่ยงการกลายพันธุ์เมื่อใดก็ตามที่เป็นไปได้ ฉันใช้โอเปอเรเตอร์ ES6 ที่นี่
const items = [1, 2, 3, 4, 5]
const insert = (arr, index, newItem) => [
// part of the array before the specified index
...arr.slice(0, index),
// inserted item
newItem,
// part of the array after the specified index
...arr.slice(index)
]
const result = insert(items, 1, 10)
console.log(result)
// [1, 10, 2, 3, 4, 5]
สามารถใช้เพื่อเพิ่มมากกว่าหนึ่งรายการโดยการปรับฟังก์ชั่นเล็กน้อยเพื่อใช้ตัวดำเนินการส่วนที่เหลือสำหรับรายการใหม่และแพร่กระจายในผลลัพธ์ที่ส่งคืนเช่นกัน
const items = [1, 2, 3, 4, 5]
const insert = (arr, index, ...newItems) => [
// part of the array before the specified index
...arr.slice(0, index),
// inserted items
...newItems,
// part of the array after the specified index
...arr.slice(index)
]
const result = insert(items, 1, 10, 20)
console.log(result)
// [1, 10, 20, 2, 3, 4, 5]
insert
วิธีการแบบกำหนดเอง/* Syntax:
array.insert(index, value1, value2, ..., valueN) */
Array.prototype.insert = function(index) {
this.splice.apply(this, [index, 0].concat(
Array.prototype.slice.call(arguments, 1)));
return this;
};
มันสามารถแทรกองค์ประกอบหลาย ๆ อย่าง (เหมือนที่เป็นเจ้าของอยู่splice
) และรองรับการโยง:
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6);
// ["b", "X", "Y", "Z", "c"]
/* Syntax:
array.insert(index, value1, value2, ..., valueN) */
Array.prototype.insert = function(index) {
index = Math.min(index, this.length);
arguments.length > 1
&& this.splice.apply(this, [index, 0].concat([].pop.call(arguments)))
&& this.insert.apply(this, arguments);
return this;
};
มันสามารถรวมอาร์เรย์จากอาร์กิวเมนต์ด้วยอาร์เรย์ที่กำหนดและยังสนับสนุนการผูกมัด:
["a", "b", "c", "d"].insert(2, "V", ["W", "X", "Y"], "Z").join("-");
// "a-b-V-W-X-Y-Z-c-d"
["b", "X", "Y", "Z", "c"]
ฉันไม่เข้าใจผลแรก ทำไมไม่"d"
รวม ดูเหมือนว่าถ้าคุณใส่ 6 เป็นพารามิเตอร์ที่สองของslice()
และมี 6 องค์ประกอบในอาร์เรย์เริ่มต้นจากดัชนีที่ระบุจากนั้นคุณควรได้รับทั้ง 6 องค์ประกอบในค่าตอบแทน (เอกสารระบุhowMany
ว่าพารามิเตอร์นั้น) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3);
=>[ ]
slice
วิธีการและไม่splice
ซึ่งคุณกำลังอ้างถึงในความคิดเห็น พารามิเตอร์ที่สองของslice
(ชื่อend
) เป็นดัชนี zero-based ที่จะสิ้นสุดการสกัด slice
สารสกัดจากขึ้นไป end
แต่ไม่รวมถึง ดังนั้นหลังจากที่insert
คุณมี["a", "b", "X", "Y", "Z", "c", "d"]
จากการที่slice
องค์ประกอบสารสกัดที่มีดัชนีจาก1
ถึง6
คือจาก"b"
ไปแต่ไม่รวมถึง"d"
"d"
มันสมเหตุสมผลหรือไม่
หากคุณต้องการที่จะแทรกองค์ประกอบหลาย ๆ อย่างลงในอาร์เรย์ในครั้งเดียวลองดูคำตอบของ Stack Overflow: วิธีที่ดีกว่าในการแบ่งอาร์เรย์ให้เป็นอาร์เรย์ในจาวาสคริปต์
นอกจากนี้ยังมีฟังก์ชั่นบางอย่างเพื่อแสดงตัวอย่างทั้งสอง:
function insertAt(array, index) {
var arrayToInsert = Array.prototype.splice.apply(arguments, [2]);
return insertArrayAt(array, index, arrayToInsert);
}
function insertArrayAt(array, index, arrayToInsert) {
Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert));
return array;
}
ในที่สุดนี่คือ jsFiddle เพื่อให้คุณเห็นด้วยตัวคุณเอง: http://jsfiddle.net/luisperezphd/Wc8aS/
และนี่คือวิธีที่คุณใช้ฟังก์ชั่น:
// if you want to insert specific values whether constants or variables:
insertAt(arr, 1, "x", "y", "z");
// OR if you have an array:
var arrToInsert = ["x", "y", "z"];
insertArrayAt(arr, 1, arrToInsert);
สำหรับการเขียนโปรแกรมที่ใช้งานได้อย่างเหมาะสมและมีจุดประสงค์ในการโยงโซ่การประดิษฐ์Array.prototype.insert()
จำเป็น จริง ๆ แล้วประกบกันอาจจะสมบูรณ์แบบถ้ามันคืนอาเรย์กลายพันธุ์แทนที่จะเป็นอาเรย์ที่ว่างเปล่าที่ไม่มีความหมายโดยสิ้นเชิง ดังนั้นที่นี่มันจะไป
Array.prototype.insert = function(i,...rest){
this.splice(i,0,...rest)
return this
}
var a = [3,4,8,9];
document.write("<pre>" + JSON.stringify(a.insert(2,5,6,7)) + "</pre>");
ตกลงข้างต้นกับArray.prototype.splice()
หนึ่งกลายพันธุ์อาร์เรย์เดิมและบางคนอาจบ่นเช่น "คุณไม่ควรแก้ไขสิ่งที่ไม่ได้เป็นของคุณ" และที่อาจกลายเป็นถูกต้องเช่นกัน ดังนั้นสำหรับสวัสดิการของประชาชนผมอยากจะให้อีกคนหนึ่งArray.prototype.insert()
ซึ่งไม่กลายพันธุ์อาร์เรย์เดิม นี่มันไป;
Array.prototype.insert = function(i,...rest){
return this.slice(0,i).concat(rest,this.slice(i));
}
var a = [3,4,8,9],
b = a.insert(2,5,6,7);
console.log(JSON.stringify(a));
console.log(JSON.stringify(b));
splice
แปรรูปอาร์เรย์เดิมผมไม่คิดว่า "โปรแกรมการทำงานที่เหมาะสม" splice
เป็นที่ใดก็ได้ในบริเวณใกล้เคียงของ
ฉันขอแนะนำให้ใช้JavaScriptบริสุทธิ์ในกรณีนี้ยังไม่มีวิธีการแทรกใน JavaScript แต่เรามีวิธีการซึ่งเป็น วิธีArrayแบบในตัวที่ทำงานให้คุณมันเรียกว่าsplice ...
มาดูกันว่ามีอะไรประกบกัน () ...
splice () วิธีการเปลี่ยนแปลงเนื้อหาของอาร์เรย์โดยการลบองค์ประกอบที่มีอยู่และ / หรือเพิ่มองค์ประกอบใหม่
ตกลงลองนึกภาพเรามีอาร์เรย์ด้านล่างนี้:
const arr = [1, 2, 3, 4, 5];
เราสามารถลบ3
ดังนี้:
arr.splice(arr.indexOf(3), 1);
มันจะส่งคืน 3 แต่ถ้าเราตรวจสอบ arr ตอนนี้เรามี:
[1, 2, 4, 5]
จนถึงตอนนี้ดีมาก แต่เราจะเพิ่มองค์ประกอบใหม่ลงในอาร์เรย์โดยใช้ตัวต่อได้อย่างไร ลองใส่ 3 กลับมาใน arr ...
arr.splice(2, 0, 3);
มาดูกันว่าเราได้ทำอะไรลงไป ...
เราใช้spliceอีกครั้ง แต่ครั้งนี้สำหรับอาร์กิวเมนต์ที่สองเราผ่าน0หมายความว่าเราต้องการลบไม่มีรายการ แต่ในเวลาเดียวกันเราเพิ่มอาร์กิวเมนต์ที่สามซึ่งเป็น 3 ที่จะถูกเพิ่มที่ดัชนีที่สอง ...
คุณควรระวังว่าเราสามารถลบและเพิ่มในเวลาเดียวกันตัวอย่างเช่นตอนนี้เราสามารถทำได้:
arr.splice(2, 2, 3);
ซึ่งจะลบ2 รายการที่ดัชนี 2 จากนั้นเพิ่ม3ที่ดัชนี 2 และผลลัพธ์จะเป็น:
[1, 2, 3, 5];
นี่แสดงให้เห็นว่าแต่ละรายการในการประกบกันทำงานอย่างไร:
array.splice (เริ่ม, ลบนับ, รายการ 1, รายการ 2, รายการ 3 ... )
ผนวกองค์ประกอบเดี่ยวที่ดัชนีเฉพาะ
//Append at specific position(here at index 1)
arrName.splice(1, 0,'newName1');
//1: index number, 0: number of element to remove, newName1: new element
//Append at specific position (here at index 3)
arrName[3] = 'newName1';
ผนวกองค์ประกอบหลายรายการที่ดัชนีเฉพาะ
//Append from index number 1
arrName.splice(1, 0,'newElemenet1', 'newElemenet2', 'newElemenet3');
//1: index number from where append start,
//0: number of element to remove,
//newElemenet1,2,3: new elements
arrName[3] = 'newName1';
จะต่อท้ายหากอาร์เรย์มีองค์ประกอบเพียง 3 องค์ประกอบ หากมีองค์ประกอบในดัชนี 3 สิ่งนี้จะถูกแทนที่ หากคุณต้องการผนวกท้ายจะดีกว่าที่จะใช้arrName.push('newName1');
Array#reduce
อีกวิธีที่เป็นไปได้กับการใช้งานของ
var arr = ["apple", "orange", "raspberry"],
arr2 = [1, 2, 4];
function insert(arr, item, index) {
arr = arr.reduce(function(s, a, i) {
i == index ? s.push(item, a) : s.push(a);
return s;
}, []);
console.log(arr);
}
insert(arr, "banana", 1);
insert(arr2, 3, 2);
นี่คือสองวิธี:
const array = [ 'My', 'name', 'Hamza' ];
array.splice(2, 0, 'is');
console.log("Method 1 : ", array.join(" "));
หรือ
Array.prototype.insert = function ( index, item ) {
this.splice( index, 0, item );
};
const array = [ 'My', 'name', 'Hamza' ];
array.insert(2, 'is');
console.log("Method 2 : ", array.join(" "));
แม้ว่าจะได้รับคำตอบนี้แล้ว แต่ฉันกำลังเพิ่มบันทึกย่อนี้สำหรับวิธีการอื่น
ฉันต้องการวางจำนวนที่รู้จักของรายการลงในอาร์เรย์ในตำแหน่งที่เฉพาะเจาะจงเมื่อพวกเขาออกมาจาก "อาเรย์ร่วม" (เช่นวัตถุ) ซึ่งตามคำนิยามไม่รับประกันว่าจะเรียงตามลำดับ ฉันต้องการให้อาร์เรย์ผลลัพธ์เป็นอาร์เรย์ของวัตถุ แต่วัตถุจะอยู่ในลำดับที่เฉพาะเจาะจงในอาร์เรย์เนื่องจากอาร์เรย์รับประกันคำสั่งของพวกเขา ดังนั้นฉันจึงทำสิ่งนี้
ก่อนวัตถุต้นฉบับสตริง JSONB ดึงจาก PostgreSQL ฉันต้องการให้เรียงลำดับตามคุณสมบัติ "สั่งซื้อ" ในวัตถุลูกแต่ละรายการ
var jsonb_str = '{"one": {"abbr": "", "order": 3}, "two": {"abbr": "", "order": 4}, "three": {"abbr": "", "order": 5}, "initialize": {"abbr": "init", "order": 1}, "start": {"abbr": "", "order": 2}}';
var jsonb_obj = JSON.parse(jsonb_str);
เนื่องจากจำนวนโหนดในวัตถุเป็นที่รู้จักกันฉันจึงสร้างอาร์เรย์ที่มีความยาวที่ระบุ:
var obj_length = Object.keys(jsonb_obj).length;
var sorted_array = new Array(obj_length);
จากนั้นวนวัตถุให้วางวัตถุชั่วคราวที่สร้างขึ้นใหม่ลงในตำแหน่งที่ต้องการในอาเรย์โดยไม่ต้องทำการ "คัดแยก"
for (var key of Object.keys(jsonb_obj)) {
var tobj = {};
tobj[key] = jsonb_obj[key].abbr;
var position = jsonb_obj[key].order - 1;
sorted_array[position] = tobj;
}
console.dir(sorted_array);
ทุกคนที่ยังคงมีปัญหากับตัวนี้และได้ลองตัวเลือกทั้งหมดข้างต้นและไม่เคยได้รับมัน ฉันกำลังแบ่งปันโซลูชันของฉันนี่คือการพิจารณาว่าคุณไม่ต้องการระบุคุณสมบัติของวัตถุของคุณและอาร์เรย์อย่างชัดเจน
function isIdentical(left, right){
return JSON.stringify(left) === JSON.stringify(right);
}
function contains(array, obj){
let count = 0;
array.map((cur) => {
if(this.isIdentical(cur, obj)) count++;
});
return count > 0;
}
นี่คือการรวมกันของการทำซ้ำอาร์เรย์อ้างอิงและเปรียบเทียบกับวัตถุที่คุณต้องการตรวจสอบแปลงทั้งสองเป็นสตริงแล้ววนซ้ำถ้ามันจับคู่ จากนั้นคุณสามารถนับได้ สามารถปรับปรุงได้ แต่นี่คือที่ฉันตัดสิน หวังว่านี่จะช่วยได้
การทำกำไรของวิธีการลดดังต่อไปนี้:
function insert(arr, val, index) {
return index >= arr.length
? arr.concat(val)
: arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
}
ดังนั้นด้วยวิธีนี้เราสามารถส่งคืนอาร์เรย์ใหม่ (จะเป็นวิธีการทำงานที่ยอดเยี่ยม - ดีกว่าการใช้การกดหรือการประกบกัน) ด้วยองค์ประกอบที่ใส่ไว้ที่ดัชนีและถ้าดัชนีมีค่ามากกว่าความยาวของอาร์เรย์จะถูกแทรก ในตอนท้าย
Array#splice()
เป็นวิธีที่จะไปเว้นแต่คุณต้องการหลีกเลี่ยงการกลายพันธุ์ของอาร์เรย์ ให้ 2 อาร์เรย์arr1
และarr2
นี่คือวิธีที่คุณจะแทรกเนื้อหาarr2
ลงในarr1
หลังจากองค์ประกอบแรก:
const arr1 = ['a', 'd', 'e'];
const arr2 = ['b', 'c'];
arr1.splice(1, 0, ...arr2); // arr1 now contains ['a', 'b', 'c', 'd', 'e']
console.log(arr1)
หากคุณมีความกังวลเกี่ยวกับกรรมวิธีอาร์เรย์ (ตัวอย่างเช่นถ้าใช้ Immutable.js), คุณสามารถใช้แทนslice()
เพื่อไม่ให้สับสนกับกับsplice()
'p'
const arr3 = [...arr1.slice(0, 1), ...arr2, ...arr1.slice(1)];
ฉันลองมันแล้วมันใช้งานได้ดี!
var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);
ดัชนีคือตำแหน่งที่คุณต้องการแทรกหรือลบองค์ประกอบ 0 นั่นคือพารามิเตอร์ที่สองกำหนดจำนวนขององค์ประกอบจากรายการดัชนีที่จะลบออกเป็นรายการใหม่ที่คุณต้องการในอาร์เรย์ มันสามารถเป็นหนึ่งหรือมากกว่าหนึ่ง
initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
นี่คือฟังก์ชั่นการทำงานที่ฉันใช้ในแอปพลิเคชันของฉัน
ตรวจสอบว่ารายการออกจากรายการ
let ifExist = (item, strings = [ '' ], position = 0) => {
// output into an array with empty string. Important just in case their is no item.
let output = [ '' ];
// check to see if the item that will be positioned exist.
if (item) {
// output should equal to array of strings.
output = strings;
// use splice in order to break the array.
// use positition param to state where to put the item
// and 0 is to not replace an index. Item is the actual item we are placing at the prescribed position.
output.splice(position, 0, item);
}
//empty string is so we do not concatenate with comma or anything else.
return output.join("");
};
แล้วฉันจะเรียกมันว่าด้านล่าง
ifExist("friends", [ ' ( ', ' )' ], 1)} // output: ( friends )
ifExist("friends", [ ' - '], 1)} // output: - friends
ifExist("friends", [ ':'], 0)} // output: friends:
หัวข้อเก่ากว่าเล็กน้อย แต่ฉันต้องเห็นด้วยกับ Redu ข้างต้นเพราะ splice มีอินเตอร์เฟสที่สับสนเล็กน้อย และการตอบสนองที่ได้รับจาก cdbajorin ว่า "มันจะส่งกลับเฉพาะอาเรย์ที่ว่างเปล่าเมื่อพารามิเตอร์ที่สองคือ 0 ถ้ามันมากกว่า 0 มันจะส่งกลับรายการที่ถูกลบออกจากอาเรย์" คือในขณะที่ถูกต้องพิสูจน์จุด ความตั้งใจของฟังก์ชั่นนี้คือการประกบกันหรือตามที่กล่าวไว้ก่อนหน้านี้โดย Jakob Keller "เพื่อเข้าร่วมหรือเชื่อมต่อรวมถึงการเปลี่ยนแปลงคุณมีอาร์เรย์ที่กำหนดไว้แล้วว่าคุณกำลังเปลี่ยนแปลงซึ่งจะเกี่ยวข้องกับการเพิ่มหรือลบองค์ประกอบ .... " ค่าส่งคืนขององค์ประกอบ (ถ้ามี) จะถูกลบออกอย่างไม่น่าเชื่อ และฉันเห็นด้วย 100% ว่าวิธีนี้น่าจะเหมาะกับการผูกมัดถ้ามันคืนสิ่งที่ดูเหมือนเป็นธรรมชาติไปแล้วอาร์เรย์ใหม่ที่มีองค์ประกอบต่อเติมเพิ่ม จากนั้นคุณสามารถทำสิ่งต่าง ๆ เช่น ["19", "17"]. splice (1,0, "18"). เข้าร่วม ("... ") หรืออะไรก็ตามที่คุณต้องการด้วยอาเรย์ที่คืนค่า ความจริงที่ว่ามันคืนสิ่งที่ถูกลบไปเป็นเพียงแค่เรื่องไร้สาระ IMHO หากความตั้งใจของวิธีการคือ "ตัดองค์ประกอบออก" และนั่นก็เป็นเพียงเจตนาเท่านั้น ดูเหมือนว่าถ้าฉันไม่รู้ว่าฉันตัดออกไปแล้วฉันอาจมีเหตุผลเล็กน้อยที่จะตัดองค์ประกอบเหล่านั้นออกมาใช่ไหม? มันจะดีกว่าถ้ามันทำตัวเหมือน concat, map, ลด, slice, ฯลฯ โดยที่ array ใหม่นั้นถูกสร้างขึ้นมาจาก array ที่มีอยู่แทนที่จะทำการกลายพันธุ์ array ที่มีอยู่ สิ่งเหล่านี้ล้วนเป็นโซ่และนั่นเป็นประเด็นที่สำคัญ มันค่อนข้างบ่อยในการจัดการอาเรย์โซ่ ดูเหมือนว่าภาษาจะต้องไปทิศทางใดทิศทางหนึ่งและพยายามที่จะยึดติดกับมันให้มากที่สุด จาวาสคริปต์นั้นใช้งานได้และมีการประกาศน้อยกว่าดูเหมือนว่าเป็นการเบี่ยงเบนที่แปลกจากบรรทัดฐาน
วันนี้ (2020.04.24) ฉันทำการทดสอบเพื่อหาวิธีแก้ปัญหาที่เลือกสำหรับอาร์เรย์ขนาดใหญ่และขนาดเล็ก ฉันทดสอบพวกเขาใน MacOs High Sierra 10.13.6 บน Chrome 81.0, Safari 13.1, Firefox 75.0
สำหรับเบราว์เซอร์ทั้งหมด
slice
และreduce
(D, E, F) มักจะเร็วกว่า 10x-100x ที่โซลูชันแบบแทนที่splice
(AI, BI, CI) นั้นเร็วที่สุด (บางครั้ง ~ 100x - แต่ขึ้นอยู่กับขนาดอาร์เรย์)การทดสอบแบ่งออกเป็นสองกลุ่ม: การแก้ปัญหาในสถานที่ (AI, BI, CI) และการแก้ปัญหาในสถานที่ (D, E, F) และดำเนินการสองกรณี
โค้ดที่ทดสอบจะแสดงเป็นตัวอย่างด้านล่าง
ตัวอย่างผลลัพธ์สำหรับอาร์เรย์ขนาดเล็กบนโครเมียมอยู่ด้านล่าง