CairoCoder
CairoCoder

Reputation: 3189

Javascript | Loop through array of objects using against an object

I have an array of objects as following:

const objArray = [
    {scope: "xx", sector: "yy", status: "pending", country: "USA"},
    {scope: "zz", sector: "yy", status: "pending", country: "USA"}
    {scope: "xx", sector: "yy", status: "pending", country: "USA"}
]

And an object as following:

const compare = {scope: "xx", sector: "yy"}

or that one:

const compare = {scope: "xx"}

or that one:

const compare = {scope: "yy"}

I want to loop through the array of objects using one of those three compare objects, and return all objects that match with any one of those three compare examples objects with same scope and sector or scope only or sector only.

I have tried .filter() function, but didn't get it to work:

const filteredCards = objArray.filter(card =>{
    return card.scope   === compare.scope
        && card.sector  === compare.sector;
});

Upvotes: 2

Views: 112

Answers (3)

ggorlen
ggorlen

Reputation: 56935

Filter is the way to go, but we may as well make the test dynamic instead of hardcoding the fields in question. Let's write a function that accepts the data array and filters by a query object, returning only items in the array that have a matching value for every property in the query object:

const filterByQuery = (data, query) => 
  data.filter(e => Object.entries(query).every(([k, v]) => e[k] === v))
;

const data = [
  {scope: "xx", sector: "yy", status: "pending", country: "USA"},
  {scope: "zz", sector: "yy", status: "pending", country: "USA"},
  {scope: "xx", sector: "yy", status: "pending", country: "USA"}
];

[
  {scope: "xx", sector: "yy"},
  {scope: "xx"},
  {scope: "yy"},
].forEach(query => console.log(filterByQuery(data, query)));

Upvotes: 3

wdev733
wdev733

Reputation: 124

Please try this code.

const compare = {scope: "xx"};

const objArray = [
    {scope: "xx", sector: "yy", status: "pending", country: "USA"},
    {scope: "zz", sector: "yy", status: "pending", country: "USA"},
    {scope: "xx", sector: "yy", status: "pending", country: "USA"}
];


var filter_result = objArray.filter(function(item) {
  for (var key in compare) {
    if (item[key] === undefined || item[key] != compare[key])
      return false;
  }
  return true;
});

console.log(filter_result)

Upvotes: 4

Halcyon
Halcyon

Reputation: 57719

I think the issue is that your filter has optional fields so if a field is not defined in the filter any value will do. I think this will work:

const filteredCards = objArray.filter(card =>{
    return (typeof compare.scope === "undefined" || card.scope === compare.scope)
        && (typeof compare.sector === "undefined" || card.sector === compare.sector)
        && (typeof compare.status === "undefined" || card.status === compare.status)
        && (typeof compare.country === "undefined" || card.country === compare.country);
});

Either the filter does not specify a value for the field, or the value matches. Repeat for each field.

Upvotes: 1

Related Questions