Home » vue » How can I return an array of objects whose property matches an array?

How can I return an array of objects whose property matches an array?

Posted by: admin November 26, 2021 Leave a comment

Questions:

I have an array like

array = [
  { name: "john", tag: ["tag1", "tag2"] },
  { name: "doe", tag: ["tag2"] },
  { name: "jane", tag: ["tag2", "tag3"] }
];

I want to get a new array of objects which contain both “tag2” and “tag3”, but not only “tag2” or both “tag1” and “tag2”.

Result should be:

newArray = [{ name: "jane", tag: ["tag2", "tag3"] }];

I tried to do it using this process:

tags = ["tag2", "tag3"];
newArray = [];
tags.forEach(t => {
  array.forEach(data => {
    data.tag.forEach(item => {
      if (item === t) {
        newArray.push(data);
      }
    });
  });
});

But I get all the items instead.

Answers:

If I understood you correctly, you want to search through your top-level array, to find all items whose tag property is an array exactly matching ['tag2', 'tag3'].

You can achieve this by filtering your array based on the above condition.

Here’s one approach:

 
const array = [
  {
    name: 'john',
    tag: ['tag1', 'tag2']
  },
  {
    name: 'doe',
    tag: ['tag2']
  },
  {
    name: 'jane',
    tag: ['tag2', 'tag3']
  }
];

const tagsToMatchOn = ['tag2', 'tag3'];

// find all elements who's tag property exactly matches
// the above tags (in presence, not necessarily in order)
const newArray = array.filter(item => (
  item.tag.length === tagsToMatchOn.length && 
  tagsToMatchOn.every(t => item.tag.includes(t))
));

console.log(newArray);

If instead, you wanted to find all items whose tag property is an array including all of ['tag2', 'tag3'] but can also include other tags, you can try something like this:

const array = [
  {
    name: 'john',
    tag: ['tag1', 'tag2']
  },
  {
    name: 'doe',
    tag: ['tag2']
  },
  {
    name: 'jane',
    tag: ['tag2', 'tag3']
  }
];

const tagsToMatchOn = ['tag2', 'tag3'];

// find all elements who's tag property includes
// all of the above tags but can also contain others
const newArray = array.filter(item =>
  tagsToMatchOn.every(t => item.tag.includes(t))
);

console.log(newArray);

###

This mightn’t be the most elegant solution but it does return what you want.

array = [{name:'john',
          tag: ['tag1','tag2'] 
         },
         {name:'doe',
          tag: ['tag2'] 
         },
         {name:'jane',
          tag: ['tag2','tag3'] 
         }
        ];

const newArray = [];
for (let index = 0; index < array.length; index++) {
    if(array[index].tag[0] === 'tag2' && array[index].tag[1] === 'tag3') {
        newArray.push(array[index])
    }
}

or if you want to be a bit more es6:

array.forEach(element => {
  if(element.tag[0] === 'tag2' && element.tag[1] === 'tag3') {
    newArray.push(element)
  }
});

###

You can do it like this

With the help of filter and every.

What basically i am doing here is first i am lopping through each element of arr (using filter). by using every i am checking does the tag property to element contains all the tags we require. if it does than we include in our final output if not than we don’t

let arr = [{name:'john',
          tag: ['tag1','tag2'] 
         },
         {name:'doe',
          tag: ['tag2'] 
         },
         {name:'jane',
          tag: ['tag2','tag3'] 
         }
        ];
let tags = ['tag2','tag3'];
let op = arr.filter(e=> tags.every(el=> e.tag.includes(el)));
console.log(op);