3

I have to filter an array of objects based on some preferences.

The Array I need to filter looks like this:

const products = [
    {value: 'v1', color: 'blue'},
    {value: 'v1', color: 'black'},
    {value: 'v1', color: 'red'},
    {value: 'v2', color: 'green'},
    {value: 'v2', color: 'red'},
    {value: 'v3', color: 'red'},
    {value: 'v4', color: 'blue'}
]

The preferences look like this:

const preferences = [
    {type: {value: 'v1', label: 'l1'}, color: 'blue'},
    {type: {value: 'v1', label: 'l1'}, color: 'red'},
    {type: {value: 'v2', label: 'l2'}, color: 'blue'},    
    {type: {value: 'v3', label: 'l3'}, color: 'red'},
    {type: {value: 'v4', label: 'l4'}, color: 'green'}
]

The filter should return all objects that match both value AND color of the preferences. So the desired result should be:

[
    {value: 'v1', color: 'blue'},
    {value: 'v1', color: 'red'},
    {value: 'v3', color: 'red'},
]

I have tried to use the following function from the example I found here:

function filterArray(allObjects, preferenceFilter) {
  const filterKeys = Object.keys(preferenceFilter);
  return allObjects.filter(item => {
    return filterKeys.every(key => {
      if (typeof preferenceFilter[key] !== 'function') return true;
      return preferenceFilter[key](item[key]);
    });
  });
}

The problem is that I need to convert the preferences into filter criteria of the form:

{color: x => x === 'red', type: y => y === 'v1' || y === 'v3'},
{color: x => x === 'blue', type: y => y === 'v1' || y === 'v2'},
{color: x => x === 'green', type: y => y === 'v4'}

How do I do this? Or is there a better way of solving this problem.

Thanks in advance for any help!

2 Answers 2

3

Try this, I have tested it, as per your use case. It is working fine.

var final = [];
for(let i=0 ; i<products.length; i++){
    preferences.map((data)=>{
        if(data.color === products[i].color && data.type.value === products[i].value){
            final.push(data);
        }
    })

}
console.log(final)
Sign up to request clarification or add additional context in comments.

Comments

2

You can filter the products so that if preferences has some of the matches the product is selected.

const products = [
{value: 'v1', color: 'blue'},
{value: 'v1', color: 'black'},
{value: 'v1', color: 'red'},
{value: 'v2', color: 'green'},
{value: 'v2', color: 'red'},
{value: 'v3', color: 'red'},
{value: 'v4', color: 'blue'}
];

const preferences = [
{type: {value: 'v1', label: 'l1'}, color: 'blue'},
{type: {value: 'v1', label: 'l1'}, color: 'red'},
{type: {value: 'v2', label: 'l2'}, color: 'blue'},
{type: {value: 'v3', label: 'l3'}, color: 'red'},
{type: {value: 'v4', label: 'l4'}, color: 'green'}
];

const filtered = products.filter(a => preferences.some(b => b.type.value === a.value && b.color === a.color));

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.