2013-08-24 12 views
5

Przepuszczam 2 tablice do funkcji i chcę przenieść konkretny wpis z jednej tablicy do drugiej. Funkcja moveDatum sama używa metod underscorejs do odrzucania i filtrowania. Mój problem polega na tym, że oryginalne tablice nie są zmieniane, tak jakbym przekazywał tablice jako wartość, a nie jako odniesienie. Określony wpis został poprawnie przeniesiony, ale jak już powiedziałem, efekt jest tylko lokalny. Co muszę zmienić, aby zmienić oryginalne tablice?tablica zmian przekazana do funkcji

Wywołać funkcję:

this.moveDatum(sourceArr, targetArr, id) 

Funkcja sama:

function moveDatum(srcDS, trgDS, id) { 
    var ds = _(srcDS).filter(function(el) { 
     return el.uid === uid; 
    }); 
    srcDS = _(srcDS).reject(function(el) { 
     return el.uid === uid; 
    }); 
    trgDS.push(ds[0]); 
    return this; 
} 

Dzięki za pomoc

+1

Nie można tego zrobić za pomocą '.filter()' lub '.reject()', ponieważ tworzą one nowe tablice. Możesz zmienić zawartość 'targetArr', modyfikując' trgDS' za pomocą 'trgDS.push (ds [0])' (tak jak robisz), ponieważ oba odnoszą się do tej samej tablicy, ale nie możesz wywołać 'sourceArr' odnosić się do nowej tablicy przez przypisanie 'srcDS' do nowej tablicy. – nnnnnn

+0

Może znajdziesz to pytanie i wyjaśnienia przydatne: http://stackoverflow.com/questions/6605640/javascript-by-reference-vs-by-value – Stefan

+0

@nnnnnn Dzięki, myślę, że rozumiem, co jest teraz kontynuując, zasadniczo odwołuję się do srcDS do nowej tablicy utworzonej za pomocą reject() i tracę odniesienie do pierwotnie przekazanej tablicy, którą naprawdę chcę zmienić, czy istnieje prosty sposób na naprawienie tego? – macg

Odpowiedz

2

kopii na każdym meczu przed usunięciem go przy użyciu metod, które modyfikują tablic, na przykład splice.

function moveDatum(srcDS, trgDS, id) { // you pass an `id`, not `uid`? 
    var i; 
    for (i = 0; i < srcDS.length; ++i) { 
     if (srcDS[i].uid === uid) { 
      trgDS.push(srcDS[i]); 
      srcDS.splice(i, 1); 
      // optionally break here for just the first 
      i--; // remember; decrement `i` because we need to re-check the same 
       // index now that the length has changed 
     } 
    } 
    return this; 
} 
+0

dzięki tobie też mate =) – macg

+0

@macg, jeśli uważasz, że odpowiedź Pawła była pomocna, rozważcie ją. – Stefan

+0

@Stefan Zrobiłem to, ale stackoverflow nie jest zbyt troskliwy ze mną mając tylko 13 reputacji =) Potrzebuję dwóch więcej do upvote – macg

3

Jak wspomniano w komentarzach, jesteś przypisywania srcDS odwołać nową tablicę zwrócony przez .reject(), a tym samym utratę odniesienia do macierzy pierwotnie przekazanej spoza funkcji.

Trzeba wykonywać operacje tablicy bezpośrednio na oryginalnej tablicy, może coś takiego:

function moveDatum(srcDS, trgDS, id) { 
    var ds; 
    for (var i = srcDS.length - 1; i >= 0; i--) { 
     if (srcDS[i].uid === id) { 
      ds = srcDS[i]; 
      srcDS.splice(i,1); 
     } 
    } 
    trgDS.push(ds); 
    return this; 
} 

Wcześniej skonfigurować pętlę, aby przejść do tyłu, dzięki czemu nie trzeba się martwić o Indeks pętli i wychodzi z synchronizacji, gdy .splice() usuwa elementy z tablicy. Pętla powrotna oznacza również, że ds kończy się odwoływaniem do pierwszego elementu w srcDS, który pasuje, co przypuszczam, że masz zamiar odkąd twój oryginalny kod miał trgDS.push(ds[0]).

Jeśli zdajesz sobie sprawę, że tablica będzie zawierać tylko dokładnie jeden mecz, to oczywiście nie ma znaczenia, czy idziesz do przodu czy do tyłu, i możesz dodać break wewnątrz if, ponieważ nie ma sensu kontynuować pętli gdy masz już mecz.

(Także myślę, że masz literówkę, zostałeś testowania === uid zamiast === id.)

+0

dziękuje, działa jak wdzięk – macg