Roznica miedzy map, for a splice w trakcie

0

Jak dokladniej dziala map, to taki bardziej elegancki for czy moze jest bardziej sprytna:>
Mozna np. zrobic cos takiego:

let arr = [1,1,2,3,1,4,5,1,6,7,1];

arr.map( (num, index) => {
     if(num === 1)
          arr.splice(index, 1);
});

Czy beda problemy jak z forem liczacym od i = 0?
Jest na to jakies ladniejsze rozwiazanie czy pozostaje stary dobry for liczacy od konca tablicy?

0

Co chcesz osiągnąć?

0

map() można napisać jako funkcję wyższego rzędu lub metodę obiektu Array

function map(array,fn){
const el = [];
for(let i = 0; i<array.length;i++){
    el.push(fn(array[i]));
 } 
  return el;
}
const tabs = map([1,2,3],function(el){
  return el*2;
})

console.log(tabs) // tablica 2,4,6
0

Tablica ma funkcję filter przeznaczoną specjalnie do filtrowania elementów w sposób funkcyjny.

let arr = [1,1,2,3,1,4,5,1,6,7,1];

arr = arr.filter( (num) => {
     return num !== 1)
});

Zresztą polecam MDN, tam masz opisane jeszcze więcej metod Array:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

0

To tylko przykladowy kod ;p
Ok cos bardziej z zycia:

    getOrdersToDo(newOrders)
    {
        console.log("wchodzi do getOrdersToDo");
        let ordersToDoArr = [];

        this.activeOrders.map((activeOrderChain, activeIndex) => {
            let isInNewOrders = false;
            for(let i = newOrders.length-1; i >= 0; i--)
            {
                if(activeOrderChain.makerId === newOrders[i].makerId)
                {
                    isInNewOrders = true;
                    let splicedNewChain = newOrders.splice(i, 1)[0];
                    if(activeOrderChain.getMakerStep().price !== splicedNewChain.getMakerStep().price)
                        ordersToDoArr.push(this.getUpdatedOrder(activeIndex, splicedNewChain));
                }
            }
            if(!isInNewOrders)
                ordersToDoArr.push(this.getOrderToCancel(activeOrderChain));

        })
        let newMakerArr = [];
        newOrders.map((chain) => {
            let maker = chain.getMakerStep();
            maker.callback = this.newOrderCallback;
            newMakerArr.push(maker);
        });
        return ordersToDoArr = ordersToDoArr.concat(newMakerArr);
    }

Jak widac tutaj uzylem for(let i = newOrders.length-1; i >= 0; i--) z tego powodu ze wewnatrz fora splicuje elementy: let splicedNewChain = newOrders.splice(i, 1)[0];
Zastanawialem sie czy muze uzyc fora z odwrotna kolejnoscia czy moge zapisac to ladniej.

Owszem moge napisac cos w stylu:
(PSEUDO KOD):

1. filtruje activeOrders i newOrders w poszukiwaniu tego samego id i sobie tam updateuje dane.
2. filtruje activeOrders i newOrders w poszukiwaniu obiektow ktore wystepuja w activeOrders ale nie wystepuja w newOrders i je wywalam z activeOrders.
3. filtruje activeOrders i newOrders w poszukiwaniu obiektow, ktore wystepuja TYLKO w newOrders i je sobie dodaje do activeOrders

Nie zrobilem tak poniewaz mysle ze to co napisalem jest duzo szybsze. Gdybym mial filtrowac te tablice to za kazdym razem bym filtrowal wszystkie elementy w tablicy 1 i lecial po wszystkich w tablicy 2 a ze musze zrobic 3 kroki to bym tak filtrowal niepotrzebnie 3 razy co by pewnie zajelo sporo wiecej czasu niz RAZ obsluzyc i wyodrebnic obiekty ktore sa:

  • w tablicy 1 i w tablicy 2
  • sa w tablicy 1 a nie ma w tablicy 2
  • sa w tablicy 2 a nie ma w tablicy 1

No chyba ze sie myle i filtrowanie byloby szybsze? Bo ladniejsze na pewno...

0

tak na marginesie, to czemu używasz map a nie forEach? (już pomijając całą resztę. Zastanawia mnie po prostu wybór metody map do tego celu, skoro tablica ma metodę forEach przeznaczoną do iteracji po elementach tablicy, a map służy do mapowania i tworzenia nowej tablicy ze starej)

No chyba ze sie myle i filtrowanie byloby szybsze?

Nie rozumiem też, czemu tego nie sprawdzisz. Nie zrobisz sobie jakiegoś benchmarka.

Czy beda problemy jak z forem liczacym od i = 0?

Tak samo tutaj. Nie wiem, czemu nie napiszesz małego kawałka kodu i nie sprawdzisz, jak to działa w praktyce. Ja tak zawsze robię, jak czegoś nie jestem pewien z JSa.

a ze musze zrobic 3 kroki to bym tak filtrowal niepotrzebnie 3 razy co by pewnie zajelo sporo wiecej czasu niz RAZ obsluzyc i wyodrebnic obiekty ktore sa:

Z moich doświadczeń, to jeśli mam coś zrobić na tablicach, co jest dość skomplikowane i nie można tego ująć w map/reduce/filter, to zwykle najszybszym podejściem, będzie pętla for albo do/while czy while (No ale doszedłem do tego mierząc czasy wykonywania, więc sprawdzenie empiryczne). I często najbardziej czytelne to będzie.

Tylko, że to wszystko zależy co chcesz zrobić, no i "premature optimization is the root of all evil".

let isInNewOrders = false;

Tutaj ponownie podsyłam linka do MDN
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
masz tam choćby metody find czy findIndex.

Nie zrobilem tak poniewaz mysle ze to co napisalem jest duzo szybsze.

To nie myśl, tylko sprawdź. Myślenie o tym, że "coś jest szybsze" to zwykle najszybszy sposób na to, żeby zrobić coś, co nie tylko nie będzie szybsze, a wręcz przeciwnie, plus będzie słabym rozwiązaniem pod kątem kodu.

A prawda jest taka, że JavaScript w 2019 się wykonuje zwykle bardzo szybko.

Gorzej z uzyciem pamięci przez strony (należałoby to sprawdzić w Dev Toolsach, ale przypuszczam, że używanie map może mieć negatywny wpływ na pamięć. Chociaż i tak na tak małą skalę to pewnie nie ma znaczenia i tak. Chyba, żebyś tam miał nie wiadomo ile danych w tej tablicy.

0

Uzywam .map poniewaz to wynika z mojej niewiedzy, gdzies zobaczylem opis filter, map, reduce ktory przedstawial map jaka krótszą, bardziej czytelna forme fora. Zapamietalem to i zacząłem powielac ten blad:>

masz tam choćby metody find czy findIndex.

Nie znam wszystkich metod, pochodze z actionscript 3 i z tego co pamietam tam bylo cos takiego jak indexOf ale podobno dzialalo dosc wolno dlatego unikam takich rzeczy.
Fakt to jest inny jezyk wiec i inne podejscie. Chociaz pewnie w kazdym jezyku szybciej policzy 10 * 0.5 niz 10 / 2 ale to w sumie nie wynika z jezyka.

Chyba, żebyś tam miał nie wiadomo ile danych w tej tablicy.

tablica jest dosc prosta, byc moze za duzo przykladam uwagi do szybkosci heh takie zboczenie zawodowe kiedys robilem gierki na telefony komorkowe i tam trza bylo tego pilnowac.
Powoli ucze sie tego js`a ale nadal mi sie wydaje ze mysle po staremu. Ale w koncu i js i actionscript pochodza z ecmascript wiec powinnybyc do siebie podobne :-)

BTW dzieki za wskazowki.

0

Warto dodać, że filter, map i reduce jest sporo wolniejsze niż zwykła pętla for. Zatem, jeżeli szybkość ma większe znaczenie niż czytelność to warto zrezygnować z nowości ES6.

1 użytkowników online, w tym zalogowanych: 0, gości: 1