Ruby find_all vs select, what’s the deal?

Miesiąc temu nie wiedziałem absolutnie nic o języku programowania Ruby. Właśnie przeprowadziłem wywiad używając Javascript dla Flatiron School, gdzie uczą zarówno Javascript jak i Ruby. Teraz nie mogę się nim nacieszyć!

Przyjęcie do Flatiron School to był dopiero początek. Wkrótce po tym nastąpiło sto godzin wstępnej pracy w Rubim, gdzie nauczyliśmy się mnóstwa metod Rubiego, które będą nam potrzebne do budowania funkcjonalnych aplikacji.

Wśród tych metod w Rubim, find_all i select wyróżniały się, ponieważ wydawało mi się, że osiągają to samo. Początkowe badania doprowadziły mnie do znalezienia…

find_all

select

Czekaj, czyż nie są one identyczne!

Cóż, tak jakby. Głębsze zagłębienie się w dokumenty Rubiego doprowadziło mnie do odkrycia, że pod maską jest trochę więcej.

Obiekt jest wyliczalny, jeśli opisuje zestaw elementów i metodę pętli nad każdym z nich. W Rubim, Enumerable#find_all i Enumerable#select to ten sam kod. Tablice w Rubim dziedziczą po Enumerable, więc wykonanie find_all lub select na tablicy w Rubim da ten sam rezultat.

Ale sprawa zaczyna się komplikować, gdy wykonujesz pętlę nad hashem. Hash jest kolekcją par klucz-wartość. Jeśli jesteś bardziej zaznajomiony z Javascriptem, hash w Ruby jest jak obiekt w Javascript.

**Na hashu, find_all zwraca tablicę**

hash = {a: 1, b: 2, c: 3, d: 4}hash.find_all do |key, value|
value.odd?
end#would return , ] because the find_all method is #inherited from Enumerable

**Na hashu, select zwraca hash zamiast tablicy**

hash = {a: 1, b: 2, c: 3, d: 4}hash.select do |key, value|
value.odd?
end#would return {a:1, c:3}

Dlaczego więc find_all i select dają różne wyniki, gdy działają na hashu? Z Hash, find_all nadal dziedziczy po Enumerable, ale select jest przedefiniowany, aby zwracać Hash zamiast Array. Subtelna, ale istotna różnica!

Morał tej historii, zastanów się, co chcesz zwrócić, gdy używasz select lub find_all (i naprawdę każdej metody w inżynierii oprogramowania), zanim jej użyjesz!

Tak, udało się!

.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.