Skip to content
Advertisement

Build a statement from an object

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)
  )
);
Advertisement