Size: a a a

PWA — русскоязычное сообщество

2018 May 29

A

Ant in PWA — русскоязычное сообщество
Я думал может можно укоротить как то
источник

ID

Ivan Dolgov in PWA — русскоязычное сообщество
const {selectedOptionsTerrain,  selectedOptionsPopulation} = this.state
if (selectedOptionsTerrain) {
           planets = planets.filter(p => p.terrain.split(', ').includes(selectedOptionsTerrain));
       }
       if (selectedOptionsPopulation) {
           planets = planets.filter(p => p.population > selectedOptionsPopulation)
       }

Итерация первая - деструктуризация
источник

ID

Ivan Dolgov in PWA — русскоязычное сообщество
второй if перекрывает первый?
источник

A

Ant in PWA — русскоязычное сообщество
Это два селкта фильтра
источник

A

Ant in PWA — русскоязычное сообщество
если оба тру то работает 2
источник

A

Ant in PWA — русскоязычное сообщество
если один фалс то только один
источник

ID

Ivan Dolgov in PWA — русскоязычное сообщество
Dez Oxel
lodash подключён? Есть чисто функциональный стиль, очень красивый)
Я бы тоже взглянул на очень красивый вариант
источник

ID

Ivan Dolgov in PWA — русскоязычное сообщество
Ant
Это два селкта фильтра
Вообще, по уму, тебе поменять их местами, если первый отработал, то ретурн. Если нет, тогда запускается второй. В зависимости от величины массива и величины вложенного массива это может сэкономить кучу времени
источник

DO

Dez Oxel in PWA — русскоязычное сообщество
Только не пугайтесь сильно, это просто другой стиль программирования - функциональный.

Вынесем отсюда логику в функцию:
if (selectedOptionsTerrain) {
 planets = planets.filter(p => p.terrain.split(', ').includes(selectedOptionsTerrain));
}

—->
const findPlanetsByTerrain = (terrain: string) => filter(pipe(
   prop('terrain'),
   split(','),
   includes(terrain)
));


Тоже самое для второго условия:
if (this.state.selectedOptionsPopulation) {
 planets = planets.filter(planet => planet.population > this.state.selectedOptionsPopulation)
}

—->
const findPlanetsWherePopulationMoreThan = (population: number) =>
   filter((planet: Planet) => planet.population > population);


Напишем общую функцию: которая проверяет условия:
const filterPlanets = (terrain: string, population: number) => pipe(
   when(() => isPresent(terrain), findPlanetsByTerrain(terrain)),
   when(() => isPresent(population), findPlanetsWherePopulationMoreThan(population))
);
источник

DO

Dez Oxel in PWA — русскоязычное сообщество
Полный код с тестом:
const { filter, pipe, prop, split, includes, isNil, negate } = require('lodash/fp');

interface Planet {
   terrain: string;
   population: number;
}

const planets: Planet[] = [{
   terrain: 'ter1,ter2,ter3',
   population: 500000
}, {
   terrain: 'ter3,ter4,ter5',
   population: 1200000
}];

const isPresent = negate(isNil);

const when = (conditionFunc: Function, onTrueFunc: Function) => (data: any) =>
   conditionFunc(data) ? onTrueFunc(data) : data;

const filterPlanets = (terrain: string, population: number) => pipe(
   when(() => isPresent(terrain), findPlanetsByTerrain(terrain)),
   when(() => isPresent(population), findPlanetsWherePopulationMoreThan(population))
);

const findPlanetsByTerrain = (terrain: string) => filter(pipe(
   prop('terrain'),
   split(','),
   includes(terrain)
));

const findPlanetsWherePopulationMoreThan = (population: number) =>
   filter((planet: Planet) => planet.population > population);

const testFilterPlanets = () => {
   console.log('filterPlanets', filterPlanets('ter5', 1000000)(planets));
};

testFilterPlanets();
источник

DO

Dez Oxel in PWA — русскоязычное сообщество
Можно упрощать еще дальше :) А если подключить RamdaJS, то будет еще легче дышать. В примере выше мне понадобилось написать два хелпера, isPresent и when. К сожалению lodash/fp не включает when()
источник

AV

Alexey Veligura in PWA — русскоязычное сообщество
^ @dezoxel  готовая статья на медиум )
источник

ID

Ivan Dolgov in PWA — русскоязычное сообщество
Dez Oxel
Можно упрощать еще дальше :) А если подключить RamdaJS, то будет еще легче дышать. В примере выше мне понадобилось написать два хелпера, isPresent и when. К сожалению lodash/fp не включает when()
Безумно нравится сама идея ФП, но вот человек просил сократить код, а тут сократить как-то не очень получается )

Спасибо за пример!
источник

DO

Dez Oxel in PWA — русскоязычное сообщество
А что мы считаем сокращением? Если кол-во символов, я могу сейчас все в одну строку написать, будет коротко)

Я считаю правильным сравнивать вот эти куски кода, какой из них лучше читается.

Императивно с элементами ФП:
if (this.state.selectedOptionsTerrain) {
   planets = planets.filter(planet => planet.terrain.split(', ').includes(this.state.selectedOptionsTerrain));
}

if (this.state.selectedOptionsPopulation) {
   planets = planets.filter(planet => planet.population > this.state.selectedOptionsPopulation)
}


Функционально:
const filterPlanets = (terrain: string, population: number) => pipe(
   when(() => isPresent(terrain), findPlanetsByTerrain(terrain)),
   when(() => isPresent(population), findPlanetsWherePopulationMoreThan(population))
);
источник

SG

Sergey Gustun in PWA — русскоязычное сообщество
чето с ифами лучше, если честно :)
источник

ID

Ivan Dolgov in PWA — русскоязычное сообщество
Sergey Gustun
чето с ифами лучше, если честно :)
И ними привычнее, но по языку лучше с when
источник

SG

Sergey Gustun in PWA — русскоязычное сообщество
по какому языку лучше с when ?
источник

SG

Sergey Gustun in PWA — русскоязычное сообщество
ааа, все понял.
источник

SG

Sergey Gustun in PWA — русскоязычное сообщество
ну не знаю.
источник

SG

Sergey Gustun in PWA — русскоязычное сообщество
чет такое.
источник