2013-07-07 30 views
20

Chcę zamienić elementy w pewnej tablicy od elementu 0, z elementami innej tablicy o zmiennej długości. Na przykład:Jak zastąpić elementy w tablicy elementami innej tablicy

var arr = new Array(10), anotherArr = [1, 2, 3], result; 
result = anotherArr.concat(arr); 
result.splice(10, anotherArr.length); 

Czy jest jakiś lepszy sposób?

+0

oczekiwany wynik? – 1983

+0

@NagaJolokia, [1, 2, 3, niezdefiniowane, niezdefiniowane ...] –

+0

Długość === 10, prawda? – 1983

Odpowiedz

38

Możesz użyć metody splice, aby zastąpić część tablicy elementami z innej tablicy, ale musisz wywołać ją w specjalny sposób, ponieważ oczekuje ona elementów jako parametrów, a nie tablicy.

Sposób splice oczekuje parametry jak (0, anotherArr.Length, 1, 2, 3), więc należy utworzyć tablicę parametrów i wykorzystanie metody apply wywołać metodę splice z parametrami:

Array.prototype.splice.apply(arr, [0, anotherArr.length].concat(anotherArr)); 

przykład:

var arr = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']; 
var anotherArr = [ 1, 2, 3 ]; 

Array.prototype.splice.apply(arr, [0, anotherArr.length].concat(anotherArr)); 

console.log(arr); 

Wyjście:

[ 1, 2, 3, 'd', 'e', 'f', 'g', 'h', 'i', 'j'] 

Demo: http://jsfiddle.net/Guffa/bB7Ey/

+2

Jeśli pierwsza macierz jest dłuższa niż wymiana, powyższe rozwiązanie nie usunie dodatkowych elementów na końcu. Ta niewielka modyfikacja: Array.prototype.splice.apply (arr, [0, arr.length] .concat (anotherArr)); – perilandmishap

+0

@perilandmishap: Tak, o to właśnie chodziło. Jeśli chcesz zastąpić tablicę, możesz po prostu zastąpić cały obiekt: 'arr = anotherArr;'. – Guffa

+0

W menedżerach stanów w stylu Flux/Redux często pracujesz ze stałą i nie masz uprawnień do zmiany odniesienia do obiektu, więc samo wykonanie zmiany przypisania nie jest możliwe. To głupi problem, ale stan javascript jest w tej chwili trochę głupi. – perilandmishap

3

można po prostu użyć splice, można dodać nowe elementy podczas usuwania starych:

var arr = new Array(10), anotherArr = [1, 2, 3]; 

arr.splice.apply(arr, [0, anotherArr.length].concat(anotherArr)) 

Jeśli nie chcesz zmodyfikować tablicę arr, można użyć slice że zwraca płytkie kopia tablicy:

var arr = new Array(10), anotherArr = [1, 2, 3], result = arr.slice(0); 

result.splice.apply(result, [0, anotherArr.length].concat(anotherArr)); 

Alternatywnie, można użyć slice odciąć pierwsze elementy i dodając anotherArr na top:

result = anotherArr.concat(arr.slice(anotherArr.length)); 
1

Nie jestem pewien, czy to jest „lepszy” sposób, ale przynajmniej pozwala wybrać indeks początkowy (podczas gdy rozwiązanie działa tylko zaczynając od indeksu 0). Here's a fiddle.

// Clone the original array 
var result = arr.slice(0); 
// If original array is no longer needed, you can do with: 
// var result = arr; 

// Remove (anotherArr.length) elements starting from index 0 
// and insert the elements from anotherArr into it 
Array.prototype.splice.apply(result, [0, anotherArr.length].concat(anotherArr)); 

(Cholera, tak wielu ninja. :-P)

1

można po prostu ustawić długość tablicy w tym przypadku. W przypadku bardziej złożonych przypadków patrz odpowiedź @ Guffa.

var a = [1,2,3]; 
a.length = 10; 
a; // [1, 2, 3, undefined x 7] 
5

Dla każdego, kto szuka sposobu, aby zastąpić całą zawartość jednej tablicy z całą zawartością innej tablicy przy zachowaniu oryginalnej tablicy:

Array.prototype.replaceContents = function (array2) { 
    //make a clone of the 2nd array to avoid any referential weirdness 
    var newContent = array2.slice(0); 
    //empty the array 
    this.length = 0; 
    //push in the 2nd array 
    this.push.apply(this, newContent); 
}; 

Funkcja prototyp pobiera tablicę jako parametr, który będzie służyć jako nowa zawartość tablicy, klonuje ją w celu uniknięcia dziwnych odniesień, opróżnia oryginalną tablicę, a następnie przekazuje podaną tablicę jako treść. Zachowuje to oryginalną tablicę i wszelkie odniesienia.

Teraz można po prostu to zrobić:

var arr1 = [1, 2, 3]; 
var arr2 = [3, 4, 5]; 
arr1.replaceContents(arr2); 

wiem, że to nie jest ściśle co początkowe pytanie zadawał, ale kwestia ta pojawia się pierwszy podczas wyszukiwania w google, i pomyślałem, ktoś inny może znaleźć to pomocne, ponieważ była to odpowiedź, której potrzebowałem.

3

W ES6, maszynopis, Babel lub podobne można po prostu zrobić:

arr1.length = 0; // Clear your array 
arr1.push(...arr2); // Push the second array using the spread opperator 

proste.

13

W ES6 z jednej operacji, można to zrobić, aby zastąpić całą zawartość tablicy: zawartość

let a = [1, 2, 3, 4] 
let b = [5, 6, 7, 8] 

a.splice(0, a.length, ...b) 

console.log(a) // -> [5, 6, 7, 8] 

na a tablicowej, która zostanie całkowicie zastąpiony przez b treści.

Należy pamiętać, że powinno to być używane tylko w aplikacjach o znaczeniu krytycznym dla realizacji, takich jak animacje o wysokich FPS, w celu uniknięcia tworzenia nowych tablic.

Normalnie utworzyłbym nową tablicę zachowując niezmienność.

EDYCJA: Właśnie zdałem sobie sprawę, że to nie odpowiada dokładnie na pytanie, ale może pomóc niektórym pracownikom google.

+0

Ładne rozwiązanie! Jest to lepsze rozwiązanie niż w przypadku 'length', ponieważ mogę również mapować w tej samej tablicy. Na przykład. 'let a = [5, 6, 7, 8]; a.splice (0, a.length, ... a.map (x => x * x)); 'I nie wymaga ponownego przypisania do' a'. – nils

+2

Po prostu użyj 'a.splice (0, Infinity, ... b)'. Drugi argument jest nieistotny, o ile jest większy niż liczba elementów do usunięcia. –

Powiązane problemy