2009-08-28 28 views

Trả lời

119

Bạn có thể sử dụng apply để tránh eval:

var args = [start, number].concat(newItemsArray); 
Array.prototype.splice.apply(theArray, args); 

chức năng apply được sử dụng để gọi chức năng khác, với một bối cảnh nhất định và lập luận, với điều kiện như là một mảng, ví dụ:

Nếu chúng ta gọi là:

var nums = [1,2,3,4]; 
Math.min.apply(Math, nums); 

Các áp dụng chức năng sẽ thực hiện:

Math.min(1,2,3,4); 
+4

Mặc dù, nó chỉ ra tôi cần phải làm Array.prototype.splice.apply (theArray, [bắt đầu, số] .concat (newItemsArray)) như tất cả các đối số, không chỉ một số, phải ở trong một mảng. – wheresrhys

+3

+1 cho mẫu '[bắt đầu, số] .concat (mảng)'. đó là tiện lợi – Claudiu

+1

Có ai đã cố gắng nhập một lượng lớn phần tử trong Chrome không? Khoảng 130K yếu tố chúng tôi dường như có ngoại lệ Stackoverflow. Xem: http://jsfiddle.net/DcHCY/ –

23

Bọc đó vào một chức năng và bạn có được điều này:

function insertArrayAt(array, index, arrayToInsert) { 
    Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert)); 
} 

Bạn sẽ sử dụng nó như thế này:

var arr = ["A", "B", "C"]; 
insertArrayAt(arr, 1, ["x", "y", "z"]); 
alert(JSON.stringify(arr)); // output: A, x, y, z, B, C 

Bạn có thể kiểm tra xem nó trong jsFiddle này: http://jsfiddle.net/luisperezphd/Wc8aS/

6

Bạn cũng có thể thêm chức năng như vậy vào nguyên mẫu Array, nếu bạn muốn một cái gì đó gần giống với phương pháp ghép nối. Ví dụ.

Array.prototype.spliceArray = function(index, n, array) { 
    return Array.prototype.splice.apply(this, [index, n].concat(array)); 
} 

Sau đó sử dụng sẽ chỉ đơn giản là:

var array = ["A","B","C","","E","F"]; 

array.splice(3,1,"D"); 
// array is ["A","B","C","D","E","F"] 

array.spliceArray(3,3,["1","2","3"]); 
// array is ["A","B","C","1","2","3"] 

Nhìn thấy nó trong hành động ở đây: http://jsfiddle.net/TheMadDeveloper/knv2f8bb/1/

Một số lưu ý:

  • Chức năng splice đổi mảng trực tiếp, nhưng lợi nhuận một mảng các phần tử đã bị xóa ... không phải mảng ghép.
  • Mặc dù thường không khuyến khích mở rộng các lớp javascript lõi, điều này tương đối lành tính với hầu hết các khung tiêu chuẩn.
  • Mở rộng Array sẽ không hoạt động trong trường hợp các lớp mảng chuyên biệt được sử dụng, chẳng hạn như dữ liệu ImageData Uint8ClampedArray.
1

Các câu trả lời ở trên liên quan đến splice.apply và chèn mảng trong một lớp lót sẽ thổi lên ngăn xếp trong ngăn xếp tràn cho mảng lớn. Xem ví dụ tại đây: http://jsfiddle.net/gkohen/u49ku99q/ Bạn có thể phải cắt và đẩy từng mục của phần được chèn vào và còn lại của mảng ban đầu để nó hoạt động. Xem fiddle: http://jsfiddle.net/gkohen/g9abppgy/26/

Array.prototype.spliceArray = function(index, insertedArray) { 
    var postArray = this.splice(index); 
    inPlacePush(this, insertedArray); 
    inPlacePush(this, postArray); 

    function inPlacePush(targetArray, pushedArray) { 
// Not using forEach for browser compatability 
     var pushedArrayLength = pushedArray.length; 
     for (var index = 0; index < pushedArrayLength; index++) { 
      targetArray.push(pushedArray[index]); 
     } 
    } 
} 
0

Tôi muốn có một chức năng mà sẽ chỉ mất một phần của mảng nguồn vì vậy tôi có mỏ hơi khác nhau dựa tắt CMS's answer

function spliceArray(array, index, howmany, source, start, end) { 
    var arguments; 
    if(source !== undefined){ 
    arguments = source.slice(start, end); 
    arguments.splice(0,0, index, howmany); 
    } else{ 
    arguments = [index, howmany]; 
    } 
    return Array.prototype.splice.apply(array, arguments) 
} 

Array.prototype.spliceArray = function(index, howmany, source, start, end) { 
    return spliceArray(this, index, howmany, source, start, end); 
} 

Bạn có thể nhìn thấy nó tại địa chỉ: https://jsfiddle.net/matthewvukomanovic/nx858uz5/

6

Câu hỏi này thực sự cũ, nhưng với ES6, có cách đơn giản hơn để thực hiện việc này bằng cách sử dụng toán tử spread:

sourceArray.splice(index, 0, ...insertedArray) 

Nếu bạn đang sử dụng javascript chưa được biên dịch trong trình duyệt, hãy đảm bảo kiểm tra xem nó có được hỗ trợ trong trình duyệt mục tiêu của bạn tại https://kangax.github.io/compat-table/es6/#test-spread_(...)_operator hay không.


Ngoài ra, đây có thể hơi tắt chủ đề, nhưng nếu bạn không muốn hoặc cần phải sửa đổi các mảng ban đầu, nhưng có thể sử dụng một mảng mới thay vào đó, xem xét phương pháp này:

mergedArray = sourceArray.slice(0, index).concat(insertedArray, sourceArray.slice(index)) 
0

Có rất nhiều câu trả lời thông minh ở đây, nhưng lý do bạn sử dụng mối nối là để nó đặt các phần tử vào mảng hiện tại mà không tạo ra một mảng khác. Nếu bạn phải tạo mảng thành concat() để bạn có thể sử dụng apply() thì bạn đang tạo thêm 2 mảng thùng rác! Sorta đánh bại toàn bộ mục đích viết Javascript bí truyền. Bên cạnh đó nếu bạn không quan tâm đến công cụ sử dụng bộ nhớ đó (và bạn nên) chỉ dest = src1.concat(src2); nó là vô cùng dễ đọc hơn. Vì vậy, đây là số lượng nhỏ nhất của dòng của tôi trong khi ở lại câu trả lời hiệu quả.

for(let item of src) dest.push(item); 

Hoặc nếu bạn muốn polyfill nó và có một chút hỗ trợ trình duyệt tốt hơn lại:

src.forEach(function(x) { dest.push(x); }); 

Tôi chắc chắn là người đầu tiên là performant hơn (đó là một lời;), nhưng không được hỗ trợ trong tất cả các trình duyệt hiện có trong tự nhiên.

Các vấn đề liên quan