2014-10-08 11 views
5

Próbuję przenieść się bardziej w stronę programowania funkcjonalnego w aplikacjach javascript. Obecnie używam biblioteki ramda jako biblioteki bazowej do tego.Funkcjonalne podejście do usuwania elementów na liście w oparciu o zagnieżdżone wartości właściwości

Moim pragnieniem:

  1. Tworzenie removeUserFromList funkcji (nazwa użytkownika, listy), która zwraca pozycje na liście, która nie pasuje do nazwy użytkownika.
  2. Wykonaj implementację tak krótką, jak to możliwe, polegając na istniejących funkcjach w bibliotece Ramda tak bardzo, jak to możliwe.

Warunki:

się lista obiektów zagnieżdżonych użytkowniczki:

[{ 
    providers: { 
     github: { 
      login: "username1" 
     } 
    } 

}, 
{ 
    providers: { 
     github: { 
      login: "username2" 
     } 
    } 

}]  

acheived tak daleko: demo

var list = [{providers: {github: {login: "username1"}}}, 
      {providers: {github: {login: "username2"}}}]; 

var getLoginName = R.useWith(R.path('providers.github.login')); 
var isLoginNameEq = R.useWith(R.eq, getLoginName); 

isLoginNameEq(list[0], "username1") // => true 

//From this point on I am totally clueless, 
//but I believe I should combine these functions 
//with R.reject in some way. 

Plunkr:

http://plnkr.co/edit/1b5FjxV3Tcgz7kozW1jX

Pytanie:

Czy istnieje funkcja lepiej nadaje się osiągnąć coś podobnego do R.eq ale na obiektach zagnieżdżonych (może R.pathEq)?

Odpowiedz

6

Właśnie został scalony pull request dla R.pathEq. To nie będzie działać do czasu następnego wydania ramda.js (aktualna wersja to 0.6.0), ale w międzyczasie można odtworzyć go tak:

var pathEq = R.curry(function(path, val, obj) { 
    return R.eq(val, R.path(path, obj)); 
}); 

a następnie używać go tak:

var rejectThis = 'userName1'; 
var myFilter = R.useWith(R.reject, pathEq('providers.github.login'): 
var filteredList = myFilter(rejectThis, users); 
0

Rozszerzanie rozwiązania od @LudwigMagnusson, trochę, można to zrobić:

// terrible name, but I'm never good at that. 
var rejectPathVal = R.curry(function(path, val, list) { 
    return R.reject(R.pathEq(path, val), list); 
}); 

var filteredList = rejectPathVal('providers.github.login', 'userName1', list); 

i oczywiście można następnie używać go jak:

var myFilter = rejectPathVal('providers.github.login', 'userName1'); 
// ... 
var filteredList = myFilter(list); 

lub w dowolny sposób, który wybierzesz, biorąc pod uwagę, że jest w pełni zasuszony. Chociaż, jak zauważył Ludwig, pathEq nie znajduje się w wydanej wersji Ramdy, możesz go pobrać pobierając wersję HEAD z Github lub możesz użyć wersji Ludwig dostarczonej powyżej.


Ale chcę nieco podważyć twoje wymagania. Pochwalam twoją próbę przejścia do bardziej funkcjonalnego stylu. Jestem jednym z autorów Ramda, i myślę, że to świetny wybór dla biblioteki, ale to wydaje się być niepotrzebne:

Bądź wdrożenie możliwie jak najkrótszy, opierając się na istniejących funkcji w bibliotece Ramda tak dużo jak to możliwe.

Sugerowałbym, że cele czytelności powinny zawsze trwać w celach lapidarności. Oczywiście, elegancja i czytelność są często powiązane ze zwięzłością, ale "tak krótkie, jak to możliwe" nigdy nie powinno być celem samym w sobie.

+0

Dzięki, będę pamiętać, że następnym razem będzie czytelność> zwięzłość. Po prostu fajnie jest pisać krótsze programy. :) Btw. świetna praca z Ramdą. – horte

1

jeśli nie trzeba utworzyć funkcję punktu darmo, wystarczy:

var removeUserFromList= function(name, list) { 
    return R.reject(pathEq('providers.github.login', name), list); 
} 
console.log(removeUserFromList('username1', users)); 

pathEq użyciu funkcji @Ludwig Magnussen użytkownika.

Powiązane problemy