Map(), filter() i indexOf() to jedne z najbardziej przydatnych metod tablicowych udostępnionych programistom JavaScript wraz z pojawieniem się standardu ECMAScript w wersji 5. Potrafią mocno uprościć pracę i są obsługiwane przez wszystkie porządne przeglądarki (oraz IE od wersji 9 w górę).

Jeśli chcesz poznać ich zastosowanie na najprostszych do zrozumienia przykładach, zachęcam do lektury artykułu.

Metoda map()

Bardzo przydatna i banalnie prosta w działaniu metoda tablicowa. Jej ideę można opisać w ten sposób:

Weź tablicę i przepuść każdy z jej elementów przez zadaną funkcję a następnie zwróć mi tablicę z wynikami.

Najprostszy przykład zastosowania to wzięcie tablicy liczb i zwrócenie tablicy z elementami pomnożonymi przez jakąś liczbę - powiedzmy 3. Jak takie działanie moglibyśmy uzyskać bez użycia metody map()? Na przykład tak:

var wejscie = [3, 6, 11, 0],
    wyjscie = [];

for (var i = 0; i < wejscie.length; i++) {
    wyjscie[i] = wejscie[i] * 3;
}

console.log(wyjscie); // [9, 18, 33, 0]

A jak zrobić to z pomocą metody map()?

var wejscie = [3, 6, 11, 0];

function pomnoz_przez_3(liczba) {  //deklaracja funkcji, przez którą przepuścimy elementy tablicy
    return liczba * 3;
}

var wyjscie = wejscie.map(pomnoz_przez_3);

console.log(wyjscie); // [9, 18, 33, 0]

Lub bez deklarowania dodatkowej funkcji:

var wejscie = [3, 6, 11, 0];

var wyjscie = wejscie.map(function (e) { //parametr e przekazuje pojedynczy element tablicy
    return e * 3;
});

console.log(wyjscie); // [9, 18, 33, 0]

Oczywiście zastosowania metody map() mogą być dużo bardziej skomplikowane - wszystko zależy od funkcji, którą podamy jako jej parametr.

Więcej informacji: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Metoda filter()

Metoda bardzo podobna w sposobie zastosowania do map(). Jej działanie jest dokładnie takie, jak można by się spodziewać po nazwie:

Weź tablicę i zwróć mi taką, z której usunięte zostały wszystkie elementy, które nie spełniają podanych kryteriów

Przykładem zastosowania jest znalezienie w tablicy wszystkich liczb większych od zera. Bez użycia metody filter() możnaby to osiągnąć na przykład tak:

var liczby = [3, -6, 11, 1, -3],
    dodatnie = [];

for (var i = 0; i < liczby.length; i++) {
    if (liczby[i] > 0) { 
    //'pchnij' do tablicy 'dodatnie' element tablicy 'liczby' spełniający kryteria
        dodatnie.push(liczby[i]);
    }
}

console.log(dodatnie); //[3, 11, 1]

Ale jesteśmy przecież mądrzejsci i wykorzystamy metodę filter():

var liczby = [3, -6, 11, 1, -3];

function wieksze_od_zera(liczba) { //deklaracja funkcji filtrującej
    return liczba > 0;
}

var dodatnie = liczby.filter(wieksze_od_zera);

console.log(dodatnie); //[3, 11, 1]

I jeszcze wersja z funkcją inline:

var liczby = [3, -6, 11, 1, -3];

var dodatnie = liczby.filter(function (e) {
    return e > 0
});

console.log(dodatnie); //[3, 11, 1]

Prawda że proste? Ciekawym przykładem zastosowania jest rozwinięcie prototypu tablicy o kilka przydatnych metod:

Array.prototype.even = function () { //tylko liczby parzyste
    return this.filter(function (e) {
        return typeof(e) === "number" && e % 2 === 0;
    })
};
[1, 2, 3, 4, 5].even();  // [2,4]

Array.prototype.odd = function () { //tylko liczby nieparzyste
    return this.filter(function (e) {
        return typeof(e) === "number" && e % 2 === 1;
    })
};
[1, 2, 3, 4, 5].odd();  // [1,3,5]

Array.prototype.under = function (x) { //liczby mniejsze niż x
    return this.filter(function (e) {
        return typeof(e) === "number" && e % 1 === 0 && e < x;
    })
};
["b", 123.2, "a", 25, "9", 23, "c", "1"].under(4);  //  [1,2,3]

Array.prototype.over = function (x) { //liczby większe niż x
    return this.filter(function (e) {
        return typeof(e) === "number" && e % 1 === 0 && e > x;
    })
};
[1, 2, 3, 4, 5].over(4);  //  [5]

Array.prototype.inRange = function (min, max) { //liczby z podanego zakresu
    return this.filter(function (e) {
        return typeof(e) === "number" && e % 1 === 0 && e >= min && e <= max;
    })
};
[1, 2, 3, 4, 5, 8, 'e', 1].inRange(1, 3);  //  [1,2,3,1]

Więcej informacji: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Metoda indexOf()

Najprostsza z omawianych tu metod a jednocześnie niezwykle przydatna. Jej sposób działania:

Sprawdź, czy podany element występuje w tablicy. Jeśli tak, zwróć mi jego indeks, jeśli nie, zwróć wartość -1

Metoda indexOf() jest w zastosowaniu równie prosta, jak przydatna. Załóżmy, że chcemy dowiedzieć się, czy element 'JavaScript' występuje w tablicy popularnych języków programowania. Bez metody indexOf() zrobilibyśmy to w ten sposób:

var popularne_jezyki = ["Java", "C++", "JavaScript", "Python", "Ruby"],
    wystepuje = false;

for (var i = 0; i < popularne_jezyki.length; i++) {
    if (popularne_jezyki[i] === "JavaScript") {
        wystepuje = true;
        break; //wyjście z pętli po znalezieniu elementu
    }
}

console.log(wystepuje); //true

O ile prostszy będzie kod z zastosowaniem metody indexOf()? Dużo:

var popularne_jezyki = ["Java", "C++", "JavaScript", "Python", "Ruby"];

var wystepuje = popularne_jezyki.indexOf("JavaScript") !== -1;

console.log(wystepuje); //true

Więcej informacji: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

Spis wszystkich dostępnych metod tablicowych można znaleźć na stronie https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array. Niektóre z nich będę omawiał w kolejnych wpisach.