0

I have an array of objects that i need to filter by a certain criteria. I'm having trouble figuring out the logic for the if statement within the for loop. I've attached a code snippet where you can adjust the criteria and see the problem I'm trying to solve. Any thoughts or advice are greatly appreciated, thanks!

With the following criteria I should only end up with 1 found item in my foundItems array:

const criteria = {
    title: 'title',
    character: 'Z',
    type: ['second'],
};

This should(and does) return all three items:

const criteria = {
    title: 'title',
    character: '',
    type: [],
};

This should return the first two items:

const criteria = {
    title: 'title',
    character: 'R',
    type: [],
};

This should return all three items:

const criteria = {
    title: '',
    character: '',
    type: ['first','second'],
};

const data = [
    {
        label: {
            title: 'A title',
        },
        character: 'R',
        type: 'first',
    },
    {
        label: {
            title: 'Another title',
        },
        character: 'R',
        type: 'second',
    },
    {
        label: {
            title: 'A more interesting title',
        },
        character: 'Z',
        type: 'second',
    },
];

const criteria = {
    title: 'title',
    character: 'Z',
    type: ['second'],
};

const createRegEx = (value) => {
  const regex = value
    .split(' ')
    .filter(Boolean)
    .map((word) => `(?=^.*${word})`)
    .join('');

  return new RegExp(regex, 'i');
}

const foundItems = [];

for (let i = 0; i < data.length; i++) {
  const item = data[i];
  
  if (
    item.label.title.match(createRegEx(criteria.title))
    || item.character === criteria.character
    || criteria.type.includes(item.type)
  ) {
    foundItems[foundItems.length] = item;
  }
}

console.log(foundItems);

10
  • Don't you have to match all 3 criteria? Use && rather than || ? Commented Mar 1, 2018 at 1:51
  • Both, kinda... All criteria are optional but if they exist then it's && and not ||. I think that's the part I'm stuck on. If I set it to && but i only have 1 of the criteria I get 0 items back. Make sense? Commented Mar 1, 2018 at 1:53
  • 1
    Ok. thanks. You may be over complicating a little. Let me gaze a little longer. Commented Mar 1, 2018 at 1:53
  • the string title exists in all three data elements. So the given criteria and the logical OR will end up with all three selected. What am I missing? Commented Mar 1, 2018 at 1:58
  • What is the intent of using an array for type criteria while the data element for type is a string type? Commented Mar 1, 2018 at 1:59

1 Answer 1

1

This demonstrates what I believe to be your intent. Please let me know if it needs to be corrected. I took some liberty to simplify the code a bit but I didn't know if the use of regex was a requirement.

The filter method applies a filter against each data element, if the filter criteria, to coin a phrase, match, returning true retains the element.

The ternary operators are necessary to determine if an input is relevant to the match. if empty then data is not filtered on that criteria.

This last point is what I believe you were missing:

const data = [
    {
        label: {
            title: 'A title',
        },
        character: 'R',
        type: 'first',
    },
    {
        label: {
            title: 'Another title',
        },
        character: 'R',
        type: 'second',
    },
    {
        label: {
            title: 'A more interesting title',
        },
        character: 'Z',
        type: 'second',
    },
];

const criteria = {
    title: '',
    character: 'R',
    type: ['second'],
};

const foundItems = data.filter(item=>{
  let t = (criteria.title.length)
            ? item.label.title.includes(criteria.title)
            : true;
  let c = (criteria.character.length)
            ? item.character === criteria.character
            : true;
  let p = (criteria.type.length)
           ? criteria.type.includes(item.type)
           : true;
  return t && c && p;
});
console.log(foundItems);

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

1 Comment

This is exactly my intent. Thank you very much!

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.