0
const arr = [
   {label : 'lbl1', text: 'txt1'},
   {label : 'lbl2', text: 'txt2'},
   {label : 'lbl3', text: 'txt3'},
   {label : 'lbl4', text: 'txt4'},
   // much more items
];

const filterBy = [
    {label: 'lbl1',text: 'txt1'},
    {label : 'lbl4', text: 'txt4'}
    //may have 0 or more items
];

I want to dynamically filter arr by filterBy. filterBy is coming from the UI... here its just a representation of what the user can pass...

in a static way I would do:

arr.filter(x => (x.text == filterBy[0].text && x.label == filterBy[0].label) ||
   .            (x.text == filterBy[1].text && x.label == filterBy[1].label)
);

Is it possible to chain dynamic criterions in JS? Thanks

6
  • You mean that filterBy can also have not 2, but many items in it? Commented Jul 6, 2021 at 4:57
  • @ZoliSzabó yes. exactly. Commented Jul 6, 2021 at 4:57
  • filterBy is already a filtered version of arr Commented Jul 6, 2021 at 4:57
  • @RajdeepDebnath filterBy is something the use pass to, to it is totally dynamic Commented Jul 6, 2021 at 4:59
  • There can be many properties in filterBy and arr should be filtered by it. Is that right? Commented Jul 6, 2021 at 5:00

5 Answers 5

1

You can easily achieve this result using filter and some

const arr = [
  { label: "lbl1", text: "txt1" },
  { label: "lbl2", text: "txt2" },
  { label: "lbl3", text: "txt3" },
  { label: "lbl4", text: "txt4" },
];

const filterBy = [
  { label: "lbl1", text: "txt1" },
  { label: "lbl4", text: "txt4" },
];

const result = arr.filter(({ label, text }) =>
  filterBy.some((o) => o.label === label && o.text === text)
);

console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

0

You can use reduce and inside the callback use filter to get the items from arr

const arr = [{
    label: 'lbl1',
    text: 'txt1'
  },
  {
    label: 'lbl2',
    text: 'txt2'
  },
  {
    label: 'lbl3',
    text: 'txt3'
  },
  {
    label: 'lbl4',
    text: 'txt4'
  },
  //.... much more items
];

const filterBy = [{
    label: 'lbl1',
    text: 'txt1'
  },
  {
    label: 'lbl4',
    text: 'txt4'
  }
];


const res = filterBy.reduce((acc, curr) => {

  acc.push(...arr.filter(item => {
    return item.label === curr.label && item.text === curr.text
  }))

  return acc;
}, []);

console.log(res)

Comments

0

use an obj instead of an array


const arr = [
   {label : 'lbl1', text: 'txt1'},
   {label : 'lbl2', text: 'txt2'},
   {label : 'lbl3', text: 'txt3'},
   {label : 'lbl4', text: 'txt4'},
];

const filterBy = {
  criteria1:"lbl1",
  criteria2:"txt1",
  criteria3:"lbl4",
  criteria4:"txt2",
}

const filtered = arr.filter(item => filterBy["criteria1"] === item.label ||filterBy["criteria2"] === item.text)||filterBy["criteria3"] === item.label || filterBy["criteria4"] === item.text);

the other "solutions" have to make two or plus loops. while this one only do one.

while more criterias you have, the uglier it is going to look like

Comments

0

const arr = [
   {label : 'lbl1', text: 'txt1'},
   {label : 'lbl2', text: 'txt2'},
   {label : 'lbl3', text: 'txt3'},
   {label : 'lbl4', text: 'txt4'},
   // much more items
];

const filterBy = [
    {label: 'lbl1',text: 'txt1'},
    {label : 'lbl4', text: 'txt4'}
    //may have 0 or more items
];

// If you want `||` between the filters.
console.log(arr.filter(x => filterBy.some(f => f.label === x.label && f.text === x.text)));

// If you want `&&` between the filters.
console.log(arr.filter(x => filterBy.every(f => f.label === x.label && f.text === x.text)));

Comments

0

I think this is what you wants.. dynamic criterias.. using Object.keys and reduce you can get this.

const arr = [
   {label : 'lbl1', text: 'txt1'},
   {label : 'lbl2', text: 'txt2'},
   {label : 'lbl3', text: 'txt3'},
   {label : 'lbl4', text: 'txt4'},
   // much more items
];

const filterBy = [
    {label: 'lbl1',text: 'txt1'},
    {label : 'lbl4', text: 'txt4'}
];

const filtered = arr.filter(item => {
    return filterBy.some(fItem => {
           const keys = Object.keys(fItem);
           return keys.length > 0 && keys.reduce((acc, k) => {
            return acc && item[k] === fItem[k];
           }, true)
    });
});

console.log(filtered)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.