有趣的filter

js中的filter就是过滤的意思,比如,我们以什么样的方式进行过滤,得到我们想要的结果。
对,我们要的就是这个结果。
给定一个数组,我们要的是Burger(汉堡)

const restaurants = [
    {
        name: "Dan's Hamburgers",
        price: 'Cheap',
        cuisine: 'Burger',
    },
    {
        name: "Austin's Pizza",
        price: 'Cheap',
        cuisine: 'Pizza',
    },
    {
        name: "Via 313",
        price: 'Moderate',
        cuisine: 'Pizza',
    },
    {
        name: "Bufalina",
        price: 'Expensive',
        cuisine: 'Pizza',
    },
    {
        name: "P. Terry's",
        price: 'Cheap',
        cuisine: 'Burger',
    },
    {
        name: "Hopdoddy",
        price: 'Expensive',
        cuisine: 'Burger',
    },
    {
        name: "Whataburger",
        price: 'Moderate',
        cuisine: 'Burger',
    },
    {
        name: "Chuy's",
        cuisine: 'Tex-Mex',
        price: 'Moderate',
    },
    {
        name: "Taquerias Arandina",
        cuisine: 'Tex-Mex',
        price: 'Cheap',
    },
    {
        name: "El Alma",
        cuisine: 'Tex-Mex',
        price: 'Expensive',
    },
    {
        name: "Maudie's",
        cuisine: 'Tex-Mex',
        price: 'Moderate',
    },
];

我们分析这个对象数组,发现cuisine: 'Burger',接下来我们进行求值

const isBurger = ({cuisine}) => cuisine === 'Burger';
const burgerJoints = restaurants.filter(isBurger);

开始的时候我们找了Burger,接下来我们要找除了Burger之的东西
只需要找到的值不是Burger就可以了

const isNotBurger = ({cuisine}) => cuisine !== 'Burger';

从restaurant数组中取就是

const isNotBurger = restaurant => !isBurger(restaurant);

如果我们此时要找Burger和Pizza
那就是

const isBurger = ({cuisine}) => cuisine === 'Burger';
const isPizza  = ({cuisine}) => cuisine === 'Pizza';

这两者的共通点是我们可以用一个函数存着他们,然后我们想找哪个的时候,就去调用哪个

const isCuisine = comparison => ({cuisine}) => cuisine === comparison;
const isBurger  = isCuisine('Burger');
const isPizza   = isCuisine('Pizza');

如果我们不找吃的,准备找价格怎么做呢?

const isPrice = comparison => ({price}) => price === comparison;
const isCheap = isPrice('Cheap');
const isExpensive = isPrice('Expensive');

我们可以看到当我们找吃的时候和找价格的时候,代码存在一些公共点,此时我们又可以提取成为函数

const isKeyEqualToValue = key => value => object => object[key] === value;
const isCuisine = isKeyEqualToValue('cuisine');
const isPrice = isKeyEqualToValue('price');
const isBurger = isCuisine('Burger');
const isPizza = isCuisine('Pizza');
const isCheap = isPrice('Cheap');
const isExpensive = isPrice('Expensive');

我们我们要找便宜的汉堡那就是
const cheapBurgers = restaurants.filter(isCheap).filter(isBurger);
或者是

const isCheapBurger = restaurant => isCheap(restaurant) && isBurger(restaurant);
const isCheapPizza = restaurant => isCheap(restaurant) && isPizza(restaurant);

我们提取重复的代码就是

const both = (predicate1, predicate2) => value =>
  predicate1(value) && predicate2(value);
const isCheapBurger = both(isCheap, isBurger);
const isCheapPizza = both(isCheap, isPizza);
const cheapBurgers = restaurants.filter(isCheapBurger);
const cheapPizza = restaurants.filter(isCheapPizza);

如果没有就是

const either = (predicate1, predicate2) => value =>
  predicate1(value) || predicate2(value);
const isDelicious = either(isBurger, isPizza);
const deliciousFood = restaurants.filter(isDelicious);

如果想要两种以上的食物就是

const isDelicious = restaurant =>
  [isPizza, isBurger, isBbq].some(predicate => predicate(restaurant));
const isCheapAndDelicious = restaurant =>
  [isDelicious, isCheap].every(predicate => predicate(restaurant));

我们进行抽象就是

const isEvery = predicates => value =>
  predicates.every(predicate => predicate(value));
const isAny = predicates => value =>
  predicates.some(predicate => predicate(value));
const isDelicious = isAny([isBurger, isPizza, isBbq]);
const isCheapAndDelicious = isEvery([isCheap, isDelicious]);

本文提炼自https://zcfy.cc/article/level-up-your-filter-game
by我还差的很远很远

原文地址:https://www.cnblogs.com/smart-girl/p/10250554.html