Baza wiedzy
Tym wpisem chciałbym zainicjować cykl krótkich artykułów o ciekawych bibliotekach, frameworkach, których miałem okazję używać, i podzielić się kilkoma spostrzeżeniami na ich temat.
Jeszcze ładnych parę lat temu zachwyciłem się uniwersalnością i prostotą biblioteki lodash. Była ona wówczas remedium na wszystkie popularne bolączki, jakich doświadczał chyba każdy programista JavaScript-u. Realizuje ona filozofię głoszoną przez jQuery, tzn. write less, do more. Redukuje często występujące problemy do pojedynczych instrukcji. Cały czas jest bardzo popularna. Gdy wejdziemy na główną stronę menedżera pakietów npm, to lodasha znajdziemy na szczycie listy pakietów zależnych. Dodatkową zaletą jest jej modułowość - możemy dołączyć do naszego projektu wyłącznie te elementy, które będą nam potrzebne, redukując w ten sposób rozmiar.
Jako koronny przykład użycia tej biblioteki podam konieczność operowania na kolekcjach. Użyjemy w tym celu przede wszystkim funkcji: each, filter, map, find itd. W połączeniu z użyciem "arrow functions" dostajemy naprawdę zgrabny kod - to oczywiście moje subiektywne odczucie, zwłaszcza dla kogoś, kto wcześniej zachwycał się LINQ w C#.
Warto też wspomnieć, że inspiracją do powstania lodasha jest inna nie mniej popularna biblioteka underscore, która realizuje te same zadania co lodash, jednak twórcy tej drugiej chwalą się uspójnieniem zachowania niektórych funkcji – chodziło o mutację (bądź jej brak) obiektów, na których wywołujemy te funkcje.
Przyznam szczerze: do niedawna uważałem, że dołączenie tej biblioteki do każdego, nawet najmniejszego projektu jest czymś oczywistym. Zauważyłem niedawno (tutaj można się zacząć śmiać), że część z tych funkcji jest dostępna w czystym JS i nie trzeba do tego jakiejś kolejnej biblioteki. Mam tu na myśli przede wszystkim metody z Array.prototype. Mimo to lodash udostępnia wiele funkcji, których póki co nie znajdziemy w standardzie. Kilka z nich pokrótce opiszę.
get
To bardzo przydatna funkcja, gdy chcemy się dostać do jakiejś zagnieżdżonej własności obiektu, a nie chce nam się na każdym poziomie sprawdzać, czy obiekt nie jest null (lub ogólnie konwersja obiektu do boolean daje wynik false).var fragmentSamochodu = { 'koło': [{ 'opona': { 'średnica': 3 } }] };
_.get(fragmentSamochodu, 'koło.opona.średnica', 5);
W takiej sytuacji nie musimy się zastanawiać, czy samochód ma koło, a koło z kolei czy ma oponę, a na końcu czy ma zdefiniowaną średnicę. Gdy któregoś elementu po drodze nie ma, wówczas otrzymamy domyślną wartość 5.
range
Przydatna, gdy chcemy wygenerować tablicę liczb o zadanym zakresie.
clone
Wykonuje płytkie klonowanie obiektu. Jest jeszcze wersja z klonowaniem głębokim cloneDeep.
assign
Do jednego obiektu dopisywane są właściwości z drugiego obiektu. Jeśli w docelowym obiekcie są już jakieś właściwości, które występują w obiekcie źródłowym, wówczas zostaną one nadpisane.
flatten
Spłaszcza tablicę tablic, ale tylko do jednego poziomu. Jest jeszcze wersja flattenDeep, która robi to rekurencyjnie do końca._.flatten(['Ala', ['ma'], 'kota']);
Wynik to: ['Ala', 'ma', 'kota'].
fromPairs
Doskonała funkcja do konwersji tablicy tablic na obiekt. Na wejściu podajemy tablicę, której elementami są tablice dwuelementowe, z której pierwszy element to klucz tworzonego obiektu, a drugi to wartość tego klucza._.fromPairs([['długość', 5], ['szerokość', 2.5]]);
Wynik to:{długość: 5, szerokość: 2.5}
. Istnieje też funkcja odwrotna: toPairs.
sortBy
Od tej pory sortowanie nie może być prostsze. Jako argument, poza oczywiście tablicą, podajemy sposób sortowania, który może być zdefiniowany jako
- funkcja zwracająca prymitywną wartość, po której można już łatwo posortować, albo
- tablicę nazw właściwości, po których należy sortować.
Oczywiście użycie tej funkcji ma sens wówczas, gdy chcemy posortować tablicę obiektów. Wtedy największą zwięzłość osiąga się tym drugi sposobem. Np. gdy chcemy posortować koła po promieniu opony, to napiszemy:_.sortBy(tablicaKół, ['opona.średnica']);
groupBy
Kolejna funkcja, która uprości kod. Wywołanie podobne jak w przypadku sortBy z tą różnicą, że teraz wskazujemy metodę grupowania. Jako wynik dostaniemy obiekt z kluczami reprezentującymi wyznaczone grupy, a wartości tych kluczy będą tablicami obiektów przyporządkowanych do danej grupy.
Tak jak wspomniałem na początku, jest też garść funkcji, które są obecnie dostępne "za darmo" w czystym JS, operujących na tablicach. Są to między innymi: each, map, filter, reduce. Wersje lodash-owe mają jednak tę zaletę, że działają również na "null-owych" kolekcjach. Np. wywołanie_.filter(null, e => true)
da nam w wyniku pustą tablicę.
Kończąc odpowiem na zadane w tytule pytanie. Biblioteka lodash oferuje naprawdę dużo ciekawych funkcji. Wymieniłem ich tylko kilka. Dokumentacja jest napisana przejrzyście. Każda funkcja jest zilustrowana przykładem. Funkcje pogrupowane są w kategorie w zależności od zastosowań. Myślę, że każdy znajdzie tam dla siebie zbiór funkcji, które ułatwią kodowanie. I pomimo tego, że możliwości języka JS sukcesywnie się zwiększają, to używanie lodasha cały czas jest uzasadnione.
Zainteresował Cię ten wpis?
Chcesz dowiedzieć się więcej?
Michał Gierwatowski
Programista wszechstronny, od języka Progress4GL począwszy, przez Javę, na TypeScripcie kończąc. Ponad piętnastoletnie doświadczenie w wytwarzaniu różnego rodzaju systemów informatycznych. Ostatnio interesuje się nowinkami w ekosystemie JavaScript/node.js
Michał.Gierwatowski(at)monolit-it.pl
Zobacz wszystkie artykuły danego autora »