2009-08-28 16 views

Odpowiedz

119

Można użyć apply uniknąć eval:

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

funkcja apply służy do połączenia z inną funkcję w danej sytuacji i argumentów, podana w tablicy, na przykład:

Jeżeli nazywamy:

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

Funkcja zastosować wykona:

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

Chociaż, okazuje się, że muszę zrobić Array.prototype.splice.apply (theArray, [start, number] .concat (newItemsArray)), ponieważ wszystkie argumenty, a nie tylko niektóre, muszą znajdować się w jednej tablicy. – wheresrhys

+3

+1 dla wzorca '[początek, liczba] .concat (tablica)'. to jest fajne – Claudiu

+1

Czy ktoś próbował wprowadzić dużą liczbę elementów w Chrome? Około 130 tysięcy elementów wydaje nam się otrzymywać wyjątek Stackoverflow. Zobacz: http://jsfiddle.net/DcHCY/ –

23

owijane że do funkcji i uzyskać w ten sposób:

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

będzie go używać tak:

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

Możesz to sprawdzić w tym jsFiddle: http://jsfiddle.net/luisperezphd/Wc8aS/

6

Możesz również dodać taką funkcję do prototypu Array, jeśli chcesz czegoś, co jest prawie identyczne z metodą łączenia. Na przykład.

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

Następnie wykorzystanie byłoby po prostu:

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

Zobacz go w akcji tutaj: http://jsfiddle.net/TheMadDeveloper/knv2f8bb/1/

Kilka uwag:

  • Funkcja splice modyfikuje tablicę bezpośrednio, ale zwraca tablica elementów, które zostały usunięte ... a nie tablica składająca się ze splicingu.
  • Chociaż normalnie nie zaleca się rozszerzania klas rdzenia javascript, jest to stosunkowo łagodne w przypadku większości standardowych frameworków.
  • Rozszerzenie Array nie zadziała w przypadku użycia wyspecjalizowanych klas macierzy, takich jak dane ImageData Uint8ClampedArray.
1

Powyższe odpowiedzi obejmują splice.apply i wstawienie tablicy do jednej linijki spowoduje wysadzenie stosu w przepełnieniu stosu dla dużej tablicy. Zobacz przykład tutaj: http://jsfiddle.net/gkohen/u49ku99q/ Możliwe, że będziesz musiał wycinać i wciskać każdy element wstawionej i pozostałej części oryginalnej tablicy, aby działał. See skrzypce: 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

chciałem mieć funkcję, która zajmie tylko część tablicy źródłowej więc mam kopalnia nieco inny oparty off 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); 
} 

Można go zobaczyć na stronie: https://jsfiddle.net/matthewvukomanovic/nx858uz5/

6

To pytanie jest naprawdę stare, ale z ES6 jest prostszy sposób, aby to zrobić za pomocą operatora rozprzestrzeniania:

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

Jeśli używasz nieskompilowanego javascript w przeglądarce, upewnij się, że jest on obsługiwany w przeglądarce docelowej pod adresem https://kangax.github.io/compat-table/es6/#test-spread_(...)_operator.


Również może to być trochę off topic, ale jeśli nie chcą lub muszą zmodyfikować oryginalną tablicę, ale przydałoby się nową tablicę zamiast rozważyć to podejście:

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

Jest tu wiele sprytnych odpowiedzi, ale powodem, dla którego stosujesz splice, jest umieszczanie elementów w bieżącej macierzy bez tworzenia innej. Jeśli musisz utworzyć tablicę do concat(), możesz użyć apply(), a następnie utworzysz 2 dodatkowe tablice kosza! Sorta pokonuje cały cel pisania ezoterycznego Javascriptu. Poza tym, jeśli nie dbasz o to użycie pamięci (i powinieneś) po prostu dest = src1.concat(src2); jest nieskończenie bardziej czytelny. Oto moja najmniejsza liczba linii przy zachowaniu skutecznej odpowiedzi.

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

Lub jeśli chcesz PolyFill go i mieć trochę lepsze wsparcie przeglądarki powrotem:

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

Jestem pewien, że pierwszy jest bardziej wydajnych (to słowo), ale nie obsługiwane we wszystkich przeglądarkach na wolności.

Powiązane problemy