Hi I have the biggest brain freeze, I’m trying to filter an array by key and value pairs stored in an object, problem I have is currently it just filters recursively like as if it was an AND operator between, but I’d like it to filter as if each statement was optional like an OR operator was between each filter.
This is the code I have currently
Object.entries(filterCond).forEach(([key, value])=> { filtered = filtered.filter(function(){ return jQuery(this).data(key).includes(+value) }) })
where filterCond contains the key value pair for the data attribute, if something is unclear feel free to ask Ill do my best to re-elaborate
Advertisement
Answer
Filter filtered
so that each value has a callback called just once, and in the callback, check that .some
of the filterCond
are met.
Your this
also incorrectly refers to the window inside your current callback – refer to the element being iterated over by using the callback’s argument.
const elementsWithAtLeastOneMatch = filtered.filter( element => Object.entries(filterCond).some( ([key, value]) => $(element).data(key)?.includes(+value) ) );
Demo:
const filterCond = { prop: '3', prop2: 'another', }; const elements = [...$('.foo')]; const elementsWithAtLeastOneMatch = elements.filter( element => Object.entries(filterCond).some( ([key, value]) => $(element).data(key)?.includes(+value) ) ); console.log(elementsWithAtLeastOneMatch);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="foo" data-prop="'3'"></div> <div class="foo" data-prop="'4'"></div> <div class="foo"></div>
But if the values you’re looking for are in data attributes, there’s no need to rely on a big library like jQuery for something so easy.
const elementsWithAtLeastOneMatch = filtered.filter( element => Object.entries(filterCond).some( ([key, value]) => element.dataset[key]?.includes(+value) ) );