我有一个汽车列表,我想根据过滤器对象(汽车)对其进行过滤:
const cars = [
{original: {"make": "audi", "model": "a4"}},
{original: {"make": "bmw", "model": "m5"}},
{original: {"make": "mercedes", "model": "s"}},
{original: {"make": "audi", "model": "a6"}},
];
过滤器对象,对于同一属性可以有多个条件(这些应被视为OR 过滤器)。该词典中的每个条目(“make”、“model”)都应被视为一个 AND 过滤器。
const filterObject = {
"make": {
filters: [
{prop: "make", value: "audi"},
{prop: "make", value: "bmw"}
]
},
"model": {
filters: [
{prop: "model", value: "a6"}
]
}
}
所以在这种情况下,我应该取回 audi - a6
。
使用 ramda 我可以做到这一步:
filter(
where({
make: equals("audi"),
model: equals("a6")
}),
map(x => x.original, data)
)
哪个有效,但有几个问题:
filterObject
是动态组装的,所以我事先不知道过滤了哪些属性。我应该以某种方式将对象映射到 where
内,但是我遇到了多个条件标准。如何让 where
了解每个属性的多个谓词?original
) 中,所以在我开始过滤之前,我映射数组以将相关部分提供给 where
函数,因此最终这个映射数组是返回。也许 where
不是正确的方法?
答案 0 :(得分:2)
R.where 需要一个对象,该对象具有您要测试的每个属性的谓词函数。通过测试对象需要满足所有谓词(和)。
要测试当前对象的 make
,让我们说“audi` 对一组选项(或),您可以使用 R.includes。
所以第一步是创建一个 where 对象,其中每个谓词都根据一组值检查当前对象的值。
const { map, pipe, prop, pluck, includes, flip, where } = R;
const createFilters = map(pipe(
prop('filters'),
pluck('value'),
flip(includes)
));
const cars = [{"original":{"make":"audi","model":"a4"}},{"original":{"make":"bmw","model":"m5"}},{"original":{"make":"mercedes","model":"s"}},{"original":{"make":"audi","model":"a6"}}];
const filterObject = {"make":{"filters":[{"prop":"make","value":"audi"},{"prop":"make","value":"bmw"}]},"model":{"filters":[{"prop":"model","value":"a6"}]}};
const filters = createFilters(filterObject);
console.log(filters);
console.log(where(filters, {"make":"audi","model":"a4"})) // false
console.log(where(filters, {"make":"audi","model":"a6"})) // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>
然后您在过滤数据时,从 origin
中获取对象,并将 R.where 与应用的过滤器一起使用:
const { map, pipe, prop, pluck, includes, flip, curry, filter, where } = R;
const createFilters = map(pipe(
prop('filters'),
pluck('value'),
flip(includes)
));
const fn = curry((filters, data) => filter(pipe(
prop('original'),
where(createFilters(filters)),
))(data));
const cars = [{"original":{"make":"audi","model":"a4"}},{"original":{"make":"bmw","model":"m5"}},{"original":{"make":"mercedes","model":"s"}},{"original":{"make":"audi","model":"a6"}}];
const filterObject = {"make":{"filters":[{"prop":"make","value":"audi"},{"prop":"make","value":"bmw"}]},"model":{"filters":[{"prop":"model","value":"a6"}]}};
const result = fn(filterObject)(cars);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>