• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Splice() w ForEach()? [JS]

VPS Starter Arubacloud
+1 głos
244 wizyt
pytanie zadane 6 kwietnia 2021 w JavaScript przez Oskar Szkurłat Bywalec (2,780 p.)

Cześć, spotkałem się z dosyć niezrozumiałą dla mnie sytuacją przy zwykłym zastosowaniu forEach() i splice() wewnątrz. Miało to na celu usunięciu wszystkich elementów z tablicy składającej się z 2 elementowych tablic, w których el[1] jest pustym znakiem. Tabela wejściowa:

history.forEach((el, idx) => {
                if (el[1] === '')
                    history.splice(idx, 1)
            })
console.table(history)

W rezultacie czego usunięto niektóre elementy, ale nie wszystkie, co na poniższej ilustracji widać.


Podejrzewałem na początku, że problemem może być usuwanie elementów tabeli podczas operacji na niej, ale nawet przy wykonaniu dodatkowej, referencyjnej tabeli wynik jest ten sam. Każdy element z tych elementów na pewno jest tym samym znakiem co do wartości '', bo to "wypluwała" poprzedzająca pętla. Dziwne również wydaje mi się, dlaczego w tym momencie, jak uruchomię forEach kilkukrotnie to usuwane są wartości, tak jakbym oczekiwał po pierwszym uruchomieniu?

for (let i = 0; i < history.length; i++)
                history.forEach((el, idx) => {
                    if (el[1] === '')
                        history.splice(idx, 1)
                })
console.table(history)


Pytam, bo chciałbym wiedzieć i zrozumieć na przyszłość, skąd taki rezultat. Z góry dziękuję za odpowiedź :)

1 odpowiedź

+2 głosów
odpowiedź 6 kwietnia 2021 przez rafal.budzis Szeryf (85,260 p.)
wybrane 6 kwietnia 2021 przez Oskar Szkurłat
 
Najlepsza
forEach zapamiętuje na którym indeksie jest obecnie :)

więc jeśli był na indeksie numer 1 (wartości : 400 i "") to usunął wartość.

Prze co wartość 500 i "" została przypisana do indeksu nr 1. W kolejnej iteracji forEach sprawdził 2 indeks (dlatego też został pominięty 1 który powinien być już sprawdzony jeszcze raz)
komentarz 6 kwietnia 2021 przez Oskar Szkurłat Bywalec (2,780 p.)

Ale właśnie w tej sytuacji ala 'referencja' nie powinna rozwiązać takiego problemu?
 

let temp = history
            history.forEach((el, idx) => {
                if (el[1] === '')
                    temp.splice(idx, 1)
            })
console.table(temp)
1
komentarz 6 kwietnia 2021 przez rafal.budzis Szeryf (85,260 p.)

Najlepszym rozwiązaniem jest funkcja filter która podczas filtrowania tworzy zawsze nową tablicy wynikową dzięki czemu nie masz taki błędów :) 
 

const result = history.filter((el) => el[1] !== '');

Referencja to dalej ta sama tablica :) Kopia mogłaby Ci pomóc też
 

const newArray = [...history];



 

komentarz 6 kwietnia 2021 przez Oskar Szkurłat Bywalec (2,780 p.)
var temp = [...history]
            temp.forEach((el, idx) => {
                if (el[1] === '')
                    history.splice(idx, 1)
            })
console.table(history)

Mój błąd, miałem na myśli kopię i faktycznie sprawdziłem przed chwilą referencję. Ale w tym momencie kopia też nie pomaga ;D a powinna na logikę.
Oczywiście faktycznie użyję filtru, tak jak się powinno.

komentarz 6 kwietnia 2021 przez rafal.budzis Szeryf (85,260 p.)
Przy kopi powinieneś iterować od końca bo teraz po prostu usuwasz nie te indeksy co trzeba ;) Z przesuwaniem indeksów zawsze jest problem ;)
1
komentarz 6 kwietnia 2021 przez Oskar Szkurłat Bywalec (2,780 p.)
Aaaa, rozumiem, będę pamiętać na przyszłość ^^ dzięki
2
komentarz 6 kwietnia 2021 przez rafal.budzis Szeryf (85,260 p.)
Nie ma sprawy. Plus dla Ciebie za dokładne opisanie problemu. (screeny pomogły) Aż się chciało odpisać :D

Podobne pytania

+1 głos
1 odpowiedź 598 wizyt
pytanie zadane 20 października 2016 w JavaScript przez Madar Obywatel (1,560 p.)
0 głosów
1 odpowiedź 257 wizyt
pytanie zadane 22 września 2022 w PHP przez NoteDS Użytkownik (560 p.)
+1 głos
1 odpowiedź 335 wizyt
pytanie zadane 4 lutego 2021 w JavaScript przez margulwb Nowicjusz (170 p.)

92,453 zapytań

141,262 odpowiedzi

319,086 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...