Umiarkowanie proste ćwiczenie, piszemy w JavaScript funkcję array_column (znaną z języka PHP) na 4 różne sposoby:

  • w klasycznej pętli
  • używając map
  • korzystając z reduce
  • korzystając z Array.from

W języku PHP mamy taką funkcję, jak array_column. Przydaje się ona do wyciągania wartości, gdy mamy do czynienia z listą obiektów, a chcemy dostać listę tylko określonej wartości. Czyli – mamy listę obiektów typu uczeń, każdy uczeń ma swoją ocenę, chcemy dostać listę ocen.

Postaramy się osiągnąć podobną funkcjonalność w JavaScript, na różne sposoby, posługując się poniższym przykładem:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Welcome to my website</h1>
    
    <script>
        const students = [
            {
            name: "John",
            grade: 5
            },
            {
            name: "Jane",
            grade: 6
            },
            {
            name: "Bob",
            grade: 4
            }
        ];
    </script>
</body>
</html>

Sposób 1 – pętla

Sposób pierwszy, czyli utworzenie nowej tablicy 'grades’, przejście w pętli po 'students’ i dodanie do grades każdej oceny. Przechodzić w pętli po tablicy możemy na różne sposoby (choćby klasyczny for, for…of, for…in), my sobie użyjemy pętli forEach:

<script>
        const students = [
            {
            name: "John",
            grade: 5
            },
            {
            name: "Jane",
            grade: 6
            },
            {
            name: "Bob",
            grade: 4
            }
        ];
        let grades = [];
        students.forEach((student)=> {
        grades.push(student.grade)
        });
        console.log(grades);
        //[5, 6, 4]
    </script>

Jak widać, forEach przechodzi po każdym elemencie students i dodaje jego ocenę do tablicy grades. Mamy wynik. Oczywiście pętla może być dowolna, na upartego nawet pętli while moglibyśmy użyć.

Sposób 2 – reduce

Jest to drugi, trudniejszy sposób. Użyjemy sobie reduce z pustą tablicą jako akumulatorem.

<script>
        const students = [
            {
            name: "John",
            grade: 5
            },
            {
            name: "Jane",
            grade: 6
            },
            {
            name: "Bob",
            grade: 4
            }
        ];
        let grades = students.reduce((acc, student) => {
         acc.push(student.grade);
         return acc;
        }, []);
        console.log(grades);
        //[5, 6, 4]
    </script>

Pusta tablica jako akumulator. Funkcja przekazana do reduce musi przyjmować argumenty akumulator i aktualny element i zwracać akumulator – i to właśnie robi.

Przechodząc po tablicy students reduce do – początkowo pustej tablicy – ładuje ocenę każdego elementu i tym samym zwraca tablicę elementów grade.

Jeżeli ten sposób nam się nie podoba – słusznie, jest mało intuicyjny. Oto nowy, lepszy sposób:

Sposób 3 – funkcja map

Ten sposób jest tak banalny, że aż muszę go pokazać. Ale najpierw małe przypomnienie, jak działa map:

const array1 = [1, 4, 9, 16];

const map1 = array1.map((x) => x * 2);

console.log(map1);
// Expected output: Array [2, 8, 18, 32]

Jeżeli nie chcemy główkować samemu, oto sposób na wyciągnięcie kolumny używając map:

  <script>
        const students = [
            {
            name: "John",
            grade: 5
            },
            {
            name: "Jane",
            grade: 6
            },
            {
            name: "Bob",
            grade: 4
            }
        ];
        let grades = students.map((student) => student.grade);
        console.log(grades);
        //[5, 6, 4]
    </script>

Funkcja przekazana do map przechodzi po każdym elemencie i „obrabia” go w sposób, jaki sobie zażyczymy, zwracając nową tablicę.

Tutaj sobie zażyczyliśmy, aby zamiast obiektu, zwrócić jego ocenę – i dostaliśmy listę ocen.

Sposób 4 – Array.from

Wprowadźmy pewne utrudnienie – teraz students nie będzie listą, ale zbiorem (Set).

<script>
        const students = new Set([
                {
                name: "John",
                grade: 5
                },
                {
                name: "Jane",
                grade: 6
                },
                {
                name: "Bob",
                grade: 4
                }
                ]);
            
    </script>

Wiemy, że Array.from jest w stanie zamienić obiekt listo-podobny do listy, zaś map wykonać to, czego chcemy.

<script>
        const students = new Set([
                {
                name: "John",
                grade: 5
                },
                {
                name: "Jane",
                grade: 6
                },
                {
                name: "Bob",
                grade: 4
                }
                ]);
        const studentsArr = Array.from(students);
        const grades = studentsArr.map((student) => student.grade);
        console.log(grades);
        //[5, 6, 4]
            
    </script>

Ale czy wiedzieliśmy, że Array.from może to zrobić za jednym razem? Jako opcjonalny, drugi argument, możemy podać funkcję, zaś Array.from zamieni nam coś tablicopodobnego na tablicę i wykona na nim map, według naszej funkcji:

<script>
        const students = new Set([
                {
                name: "John",
                grade: 5
                },
                {
                name: "Jane",
                grade: 6
                },
                {
                name: "Bob",
                grade: 4
                }
                ]);
        
        const grades = Array.from(students, (student) => student.grade);
        console.log(grades);
        //[5, 6, 4]
            
    </script>