วิธีแทรกรายการลงในอาร์เรย์ที่ดัชนีเฉพาะ (JavaScript)


2931

ฉันกำลังมองหาวิธีแทรกอาเรย์ JavaScript ในรูปแบบของ:

arr.insert(index, item)

โดยเฉพาะอย่างยิ่งใน jQuery แต่การใช้ JavaScript ใด ๆ จะทำในจุดนี้


95
โปรดทราบว่า JQuery เป็น DOM และไลบรารีการจัดการเหตุการณ์ไม่ใช่ภาษาของตนเอง มันไม่มีอะไรเกี่ยวข้องกับการจัดการอาเรย์
Domino

25
api.jquery.com/jQuery.inArrayไม่มีส่วนเกี่ยวข้องกับ DOM หรือเหตุการณ์ jQuery ได้พัฒนาเป็นชุดเครื่องมือแบบผสมสำหรับการพัฒนาเบราว์เซอร์ JS ทำให้ผู้คนคาดหวังว่าจะมีวิธีการสำหรับทุกสิ่ง
ทิม

4
@ Tim, แต่มันยังไม่ใช่ภาษาของมันเอง (ยังคงมีคำถามบางอย่างเช่น "วิธีการรวมสองตัวเลขใน jQuery" ที่นี่ดังนั้น SO)
Victor

3
@Victor ไม่และจะไม่มีวันเป็นเช่นนั้น jQuery มีประโยชน์และเกี่ยวข้อง แต่มันมีวัน
ทิม

1
ดูสิ่งนี้ด้วยความประหลาดใจที่บิดเบี้ยว (:
noobie

คำตอบ:


4756

สิ่งที่คุณต้องการคือ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());


168
ขอบคุณฉันคิดว่าฉันจะรู้สึกโง่ที่ถาม แต่ตอนนี้ฉันรู้คำตอบแล้ว! ทำไมพวกเขาถึงตัดสินใจที่จะเรียกมันว่าประกบกันเมื่อมีคำที่ค้นหาได้มากกว่าที่ใช้กันโดยทั่วไปสำหรับฟังก์ชั่นเดียวกัน!
tags2k

83
@ tags2k: เพราะฟังก์ชั่นทำมากกว่าการใส่ไอเท็มและชื่อของมันถูกสร้างขึ้นแล้วในภาษา Perl?
Christoph


55
Splice สามารถใส่ แต่เพียงเป็นบ่อยไม่ได้ ตัวอย่างเช่น: arr.splice(2,3)จะลบ 3 องค์ประกอบเริ่มต้นที่ดัชนี 2 โดยไม่ผ่านพารามิเตอร์ที่ 3 .... ไม่มีการแทรกอะไรเลย ดังนั้นชื่อinsert()ก็ไม่ยุติธรรมเช่นกัน
EBarr

14
ฉันคิดว่าคำว่า "splice" สมเหตุสมผลแล้ว Splice หมายถึงการเข้าร่วมหรือเชื่อมต่อรวมถึงการเปลี่ยนแปลง คุณมีอาร์เรย์ที่สร้างไว้แล้วซึ่งตอนนี้คุณ "เปลี่ยน" ซึ่งจะเกี่ยวข้องกับการเพิ่มหรือลบองค์ประกอบ คุณระบุตำแหน่งที่อยู่ในอาเรย์ที่จะเริ่มจากนั้นจำนวนไอเท็มเก่าที่จะลบ (ถ้ามี) และสุดท้ายเลือกรายการองค์ประกอบใหม่ที่จะเพิ่ม Splice ยังเป็นศัพท์ไซไฟที่ยอดเยี่ยมแน่นอน
Jakub Keller

286

คุณสามารถใช้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' ]

9
ในการแทรกหลายรายการคุณสามารถใช้Array.prototype.insert = function (index, items) { this.splice.apply(this, [index, 0].concat(items)); }
Ryan Smith

7
ปัญหาของการเพิ่มสิ่งต่าง ๆ ลงในอาเรย์คือฟังก์ชั่นจะแสดงเป็นองค์ประกอบเมื่อคุณทำเพื่อ (i ใน arr) {... }
rep_movsd

7
แต่โปรดจำไว้ว่าไม่แนะนำให้ขยายประเภทเนทิฟเนื่องจากอาจรบกวนการทำงานของรหัสอื่นหรือการทำงานในอนาคต
marsze

17
อย่าดัดแปลงวัตถุที่คุณไม่ได้เป็นเจ้าของ
Luis Cabrera Benito

4
อย่าแก้ไขต้นแบบ
satya164

141

นอกเหนือจากการประกบกันคุณสามารถใช้วิธีการนี้ซึ่งจะไม่กลายพันธุ์อาร์เรย์เดิม แต่จะสร้างอาร์เรย์ใหม่ด้วยรายการที่เพิ่ม คุณควรหลีกเลี่ยงการกลายพันธุ์เมื่อใดก็ตามที่เป็นไปได้ ฉันใช้โอเปอเรเตอร์ 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]


1
นี่เป็นวิธีที่ดีและปลอดภัยหรือไม่ ฉันถามเพราะมันดูสง่างามและกระชับ แต่ไม่มีคำตอบอื่นใดที่สัมผัสกับสิ่งนี้ ส่วนใหญ่ดัดแปลงวัตถุต้นแบบ!
Harsh Kanchina

5
@HarshKanchina อาจเป็นเพราะคำตอบส่วนใหญ่เป็น ES6 ก่อน แต่วิธีการนี้เป็นเรื่องธรรมดามากในตอนนี้จากประสบการณ์ของฉัน
gafi

77

insertวิธีการแบบกำหนดเอง

1. ด้วยการโต้แย้งที่หลากหลายและการสนับสนุนการโยง

/* 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"]

2. ด้วยการรวมอาร์กิวเมนต์ประเภทอาเรย์และการสนับสนุนเชน

/* 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"

DEMO: http://jsfiddle.net/UPphH/


มีวิธีกะทัดรัดในการมีรุ่นนี้ยังรวมอาร์เรย์เมื่อพบหนึ่งในการขัดแย้ง?
Nolo

["b", "X", "Y", "Z", "c"]ฉันไม่เข้าใจผลแรก ทำไมไม่"d"รวม ดูเหมือนว่าถ้าคุณใส่ 6 เป็นพารามิเตอร์ที่สองของslice()และมี 6 องค์ประกอบในอาร์เรย์เริ่มต้นจากดัชนีที่ระบุจากนั้นคุณควรได้รับทั้ง 6 องค์ประกอบในค่าตอบแทน (เอกสารระบุhowManyว่าพารามิเตอร์นั้น) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

ที่จริงแล้วถ้าฉันใช้ดัชนีตั้งแต่ 3 ตัวขึ้นไปฉันจะไม่ได้อะไรเลยในผลลัพธ์ (กรณีที่ 1, FireFox) ["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3);=>[ ]
Alexis Wilke

@AlexisWilke ในตัวอย่างแรกฉันใช้sliceวิธีการและไม่spliceซึ่งคุณกำลังอ้างถึงในความคิดเห็น พารามิเตอร์ที่สองของslice(ชื่อend) เป็นดัชนี zero-based ที่จะสิ้นสุดการสกัด sliceสารสกัดจากขึ้นไป endแต่ไม่รวมถึง ดังนั้นหลังจากที่insertคุณมี["a", "b", "X", "Y", "Z", "c", "d"]จากการที่sliceองค์ประกอบสารสกัดที่มีดัชนีจาก1ถึง6คือจาก"b"ไปแต่ไม่รวมถึง"d" "d"มันสมเหตุสมผลหรือไม่
VisioN

41

หากคุณต้องการที่จะแทรกองค์ประกอบหลาย ๆ อย่างลงในอาร์เรย์ในครั้งเดียวลองดูคำตอบของ 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);

1
จะไม่ insertAt () จะดีกว่าที่จะเรียก insertArrayAt () เมื่อมันสร้าง arrayToInsert องค์ประกอบเดียว? ที่หลีกเลี่ยงการทำซ้ำของรหัสที่เหมือนกัน
Matt Sach

1
นี่เป็นตัวอย่างที่ดีของการใช้ 'ใช้' เมื่อใด
CRice

ฉันเพิ่มพารามิเตอร์ removeCount ให้กับวิธีนี้เพื่อใช้ประโยชน์จากความสามารถของ splice ในการลบรายการที่ดัชนีนั้น: Array.prototype.splice.apply (อาร์เรย์, [ดัชนี, removeCount || 0] .concat (arrayToInsert));
CRice

23

สำหรับการเขียนโปรแกรมที่ใช้งานได้อย่างเหมาะสมและมีจุดประสงค์ในการโยงโซ่การประดิษฐ์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));


2
"อาเรย์ที่ว่างเปล่าที่ไม่มีความหมายโดยสิ้นเชิง" - มันจะส่งกลับอาเรย์ที่ว่างเปล่าเมื่อพารามิเตอร์ที่สองคือ 0 ถ้ามันมากกว่า 0 มันจะคืนค่ารายการที่ถูกลบออกจากอาเรย์ ระบุว่าคุณกำลังเพิ่มต้นแบบและspliceแปรรูปอาร์เรย์เดิมผมไม่คิดว่า "โปรแกรมการทำงานที่เหมาะสม" spliceเป็นที่ใดก็ได้ในบริเวณใกล้เคียงของ
chrisbajorin

เรากำลังพูดถึงการแทรกที่นี่และพารามิเตอร์ตัวที่สองของ Array.prototype.splice () จะต้องมีค่าเป็นศูนย์ และสิ่งที่ส่งคืนนั้นไม่มีความหมายใดนอกจาก "ฉันยังไม่ได้ลบอะไรเลย" และเนื่องจากเราใช้เพื่อแทรกรายการที่เรามีข้อมูลนั้นอยู่แล้ว หากคุณไม่ต้องการที่จะกลายพันธุ์อาเรย์ดั้งเดิมคุณสามารถทำเช่นเดียวกันกับสอง Array.prototype.slice () และ Array.prototype.concat () หนึ่งการดำเนินการ มันขึ้นอยู่กับคุณ.
Redu

1
การใช้งานครั้งที่สองของคุณนั้นสะอาดที่สุดจากทั้งหน้านี้และคุณไม่มีคะแนนโหวต โปรดสละของฉันและติดตามการทำงานที่ดี (คุณควรหลีกเลี่ยงการกลายพันธุ์ต้นแบบ แต่คุณรู้แล้ว)
NiKo

1
ฉันคิดว่าเป็นมูลค่าการกล่าวขวัญว่าพารามิเตอร์ที่เหลือเป็น ECMA 6th ใหม่ ( developer.mozilla.org/en/docs/Web/JavaScript/Reference/
......

18

ฉันขอแนะนำให้ใช้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 ... )


13

ผนวกองค์ประกอบเดี่ยวที่ดัชนีเฉพาะ

//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

8
น่าสังเกตว่า arrName [3] ไม่ได้ต่อท้าย แต่จะแทนที่
sfratini

มันเพิ่มองค์ประกอบลงในอาร์เรย์ที่มีอยู่ซึ่งไม่ผ่านการขี่ Ex: let arrName = ['xxx', 'yyy', 'zzz']; arrName.splice (1, 0, 'aaa', 'bbb', 'ccc'); หลังจากพิมพ์ arrName
Srikrushna

หาก arrName มีองค์ประกอบมากกว่า 3 รายการคุณกำลังเข้าแทนที่องค์ประกอบที่ 3 ไม่ต้องต่อท้าย หรือฉันกำลังมองสิ่งนี้ในทางที่ผิด?
sfratini

ถ้าเราแทรกองค์ประกอบที่อยู่ตรงกลางมันจะเลื่อนองค์ประกอบถัดไปที่ไม่อยู่เหนือ โปรดระบุปัญหาของคุณสิ่งที่คุณต้องการ ใช้อาร์เรย์ (ตัวอย่าง) และสิ่งที่คุณต้องการในเอาต์พุต โปรดแสดงความคิดเห็นกับฉัน
Srikrushna

1
@Srikrushna arrName[3] = 'newName1';จะต่อท้ายหากอาร์เรย์มีองค์ประกอบเพียง 3 องค์ประกอบ หากมีองค์ประกอบในดัชนี 3 สิ่งนี้จะถูกแทนที่ หากคุณต้องการผนวกท้ายจะดีกว่าที่จะใช้arrName.push('newName1');
กลัว

6

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);


6

นี่คือสองวิธี:

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(" "));


4

แม้ว่าจะได้รับคำตอบนี้แล้ว แต่ฉันกำลังเพิ่มบันทึกย่อนี้สำหรับวิธีการอื่น

ฉันต้องการวางจำนวนที่รู้จักของรายการลงในอาร์เรย์ในตำแหน่งที่เฉพาะเจาะจงเมื่อพวกเขาออกมาจาก "อาเรย์ร่วม" (เช่นวัตถุ) ซึ่งตามคำนิยามไม่รับประกันว่าจะเรียงตามลำดับ ฉันต้องการให้อาร์เรย์ผลลัพธ์เป็นอาร์เรย์ของวัตถุ แต่วัตถุจะอยู่ในลำดับที่เฉพาะเจาะจงในอาร์เรย์เนื่องจากอาร์เรย์รับประกันคำสั่งของพวกเขา ดังนั้นฉันจึงทำสิ่งนี้

ก่อนวัตถุต้นฉบับสตริง 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);

3

ทุกคนที่ยังคงมีปัญหากับตัวนี้และได้ลองตัวเลือกทั้งหมดข้างต้นและไม่เคยได้รับมัน ฉันกำลังแบ่งปันโซลูชันของฉันนี่คือการพิจารณาว่าคุณไม่ต้องการระบุคุณสมบัติของวัตถุของคุณและอาร์เรย์อย่างชัดเจน

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;
}

นี่คือการรวมกันของการทำซ้ำอาร์เรย์อ้างอิงและเปรียบเทียบกับวัตถุที่คุณต้องการตรวจสอบแปลงทั้งสองเป็นสตริงแล้ววนซ้ำถ้ามันจับคู่ จากนั้นคุณสามารถนับได้ สามารถปรับปรุงได้ แต่นี่คือที่ฉันตัดสิน หวังว่านี่จะช่วยได้


3

การทำกำไรของวิธีการลดดังต่อไปนี้:

function insert(arr, val, index) {
    return index >= arr.length 
        ? arr.concat(val)
        : arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
}

ดังนั้นด้วยวิธีนี้เราสามารถส่งคืนอาร์เรย์ใหม่ (จะเป็นวิธีการทำงานที่ยอดเยี่ยม - ดีกว่าการใช้การกดหรือการประกบกัน) ด้วยองค์ประกอบที่ใส่ไว้ที่ดัชนีและถ้าดัชนีมีค่ามากกว่าความยาวของอาร์เรย์จะถูกแทรก ในตอนท้าย


3

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)];

2

ฉันลองมันแล้วมันใช้งานได้ดี!

var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);

ดัชนีคือตำแหน่งที่คุณต้องการแทรกหรือลบองค์ประกอบ 0 นั่นคือพารามิเตอร์ที่สองกำหนดจำนวนขององค์ประกอบจากรายการดัชนีที่จะลบออกเป็นรายการใหม่ที่คุณต้องการในอาร์เรย์ มันสามารถเป็นหนึ่งหรือมากกว่าหนึ่ง

initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");

4
เพียงคัดลอกคำตอบที่วางไว้ด้านบน สิ่งนี้ไม่ได้เป็นการเพิ่มคุณค่าให้กับคำถาม ไม่ว่าคุณจะเพิ่มคำตอบใหม่หรือแสดงความคิดเห็นในที่มีอยู่ โปรดลองทำสิ่งใหม่ ๆ เราไม่ต้องการทำลายชุมชนนี้
hannad rehman

1

นี่คือฟังก์ชั่นการทำงานที่ฉันใช้ในแอปพลิเคชันของฉัน

ตรวจสอบว่ารายการออกจากรายการ

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: 

1

หัวข้อเก่ากว่าเล็กน้อย แต่ฉันต้องเห็นด้วยกับ Redu ข้างต้นเพราะ splice มีอินเตอร์เฟสที่สับสนเล็กน้อย และการตอบสนองที่ได้รับจาก cdbajorin ว่า "มันจะส่งกลับเฉพาะอาเรย์ที่ว่างเปล่าเมื่อพารามิเตอร์ที่สองคือ 0 ถ้ามันมากกว่า 0 มันจะส่งกลับรายการที่ถูกลบออกจากอาเรย์" คือในขณะที่ถูกต้องพิสูจน์จุด ความตั้งใจของฟังก์ชั่นนี้คือการประกบกันหรือตามที่กล่าวไว้ก่อนหน้านี้โดย Jakob Keller "เพื่อเข้าร่วมหรือเชื่อมต่อรวมถึงการเปลี่ยนแปลงคุณมีอาร์เรย์ที่กำหนดไว้แล้วว่าคุณกำลังเปลี่ยนแปลงซึ่งจะเกี่ยวข้องกับการเพิ่มหรือลบองค์ประกอบ .... " ค่าส่งคืนขององค์ประกอบ (ถ้ามี) จะถูกลบออกอย่างไม่น่าเชื่อ และฉันเห็นด้วย 100% ว่าวิธีนี้น่าจะเหมาะกับการผูกมัดถ้ามันคืนสิ่งที่ดูเหมือนเป็นธรรมชาติไปแล้วอาร์เรย์ใหม่ที่มีองค์ประกอบต่อเติมเพิ่ม จากนั้นคุณสามารถทำสิ่งต่าง ๆ เช่น ["19", "17"]. splice (1,0, "18"). เข้าร่วม ("... ") หรืออะไรก็ตามที่คุณต้องการด้วยอาเรย์ที่คืนค่า ความจริงที่ว่ามันคืนสิ่งที่ถูกลบไปเป็นเพียงแค่เรื่องไร้สาระ IMHO หากความตั้งใจของวิธีการคือ "ตัดองค์ประกอบออก" และนั่นก็เป็นเพียงเจตนาเท่านั้น ดูเหมือนว่าถ้าฉันไม่รู้ว่าฉันตัดออกไปแล้วฉันอาจมีเหตุผลเล็กน้อยที่จะตัดองค์ประกอบเหล่านั้นออกมาใช่ไหม? มันจะดีกว่าถ้ามันทำตัวเหมือน concat, map, ลด, slice, ฯลฯ โดยที่ array ใหม่นั้นถูกสร้างขึ้นมาจาก array ที่มีอยู่แทนที่จะทำการกลายพันธุ์ array ที่มีอยู่ สิ่งเหล่านี้ล้วนเป็นโซ่และนั่นเป็นประเด็นที่สำคัญ มันค่อนข้างบ่อยในการจัดการอาเรย์โซ่ ดูเหมือนว่าภาษาจะต้องไปทิศทางใดทิศทางหนึ่งและพยายามที่จะยึดติดกับมันให้มากที่สุด จาวาสคริปต์นั้นใช้งานได้และมีการประกาศน้อยกว่าดูเหมือนว่าเป็นการเบี่ยงเบนที่แปลกจากบรรทัดฐาน


-2

ประสิทธิภาพ

วันนี้ (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 - แต่ขึ้นอยู่กับขนาดอาร์เรย์)
  • สำหรับโซลูชัน BI อาร์เรย์ขนาดเล็กนั้นช้าที่สุด
  • สำหรับโซลูชัน E อาร์เรย์ขนาดใหญ่นั้นช้าที่สุด

ป้อนคำอธิบายรูปภาพที่นี่

รายละเอียด

การทดสอบแบ่งออกเป็นสองกลุ่ม: การแก้ปัญหาในสถานที่ (AI, BI, CI) และการแก้ปัญหาในสถานที่ (D, E, F) และดำเนินการสองกรณี

  • ทดสอบอาเรย์กับ 10 องค์ประกอบ - คุณสามารถเรียกใช้ที่นี่
  • ทดสอบอาร์เรย์ที่มีองค์ประกอบ 1,000,000 - คุณสามารถเรียกใช้ที่นี่

โค้ดที่ทดสอบจะแสดงเป็นตัวอย่างด้านล่าง

ตัวอย่างผลลัพธ์สำหรับอาร์เรย์ขนาดเล็กบนโครเมียมอยู่ด้านล่าง

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.