-1

My question is extension to this question javascript filter array multiple conditions
from that question if filter object is

{address: 'England', name: 'Mark'};

and array is

var users = [{
    name: 'John',
    email: 'johnson@mail.com',
    age: 25,
    address: 'USA'
  },
  {
    name: 'Tom',
    email: 'tom@mail.com',
    age: 35,
    address: 'England'
  },
  {
    name: 'Mark',
    email: 'mark@mail.com',
    age: 28,
    address: 'England'
  }
];

so the answer is

[
  {
    "name": "Mark",
    "email": "mark@mail.com",
    "age": 28,
    "address": "England"
  }
]

which is absolutely fine but my question is array has to be filtered for the filter object properties value
for example my filter object will be {address: 'England', name: ''} now this has to filter the array for all names and address England

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Aravind Reddy
  • 747
  • 6
  • 20
  • The posted question does not appear to include [any attempt](https://idownvotedbecau.se/noattempt/) at all to solve the problem. StackOverflow expects you to [try to solve your own problem first](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users), as your attempts help us to better understand what you want. Please edit the question to show what you've tried, so as to illustrate a specific problem you're having in a [MCVE]. For more information, please see [ask] and take the [tour]. – CertainPerformance Sep 21 '18 at 07:51
  • `users= users.filter(function(item) { for (var key in filter) { if (filter[key]=="") continue; if (item[key] === undefined || item[key] != filter[key]) return false; } return true; }); ` – mplungjan Sep 21 '18 at 08:01
  • Why not add a condition within the filter function that will check if name is truthy and only apply the name check if it is? – Nadav Sep 21 '18 at 08:08
  • thank @Nadav added it and it worked – Aravind Reddy Sep 21 '18 at 08:54

5 Answers5

1

You'd use filter on users and every on the filter object's entries

const filter = {address: 'England', name: 'Mark'};

const res = users.filter(user => 
  Object.entries(filter)
  .every(([k,v]) => v === '' || user[k] === v)
);
console.log(res);
<script>
var users = [{
  name: 'John',
  email: 'johnson@mail.com',
  age: 25,
  address: 'USA'
},
  {
    name: 'Tom',
    email: 'tom@mail.com',
    age: 35,
    address: 'England'
  },
  {
    name: 'Mark',
    email: 'mark@mail.com',
    age: 28,
    address: 'England'
  }
];
</script>
baao
  • 71,625
  • 17
  • 143
  • 203
0

From the example in the post you mention, just continue if the filter is blank

var filter = {address: 'England', name: ''}
var users = [{
    name: 'John',
    email: 'johnson@mail.com',
    age: 25,
    address: 'USA'
  },
  {
    name: 'Tom',
    email: 'tom@mail.com',
    age: 35,
    address: 'England'
  },
  {
    name: 'Mark',
    email: 'mark@mail.com',
    age: 28,
    address: 'England'
  }
];

users = users.filter(function(item) {
  for (var key in filter) {
    if (filter[key] == "") continue; // added this:
    if (item[key] === undefined || item[key] != filter[key])
      return false;
  }
  return true;
});
console.log(users)
mplungjan
  • 169,008
  • 28
  • 173
  • 236
0

You can use a combination of filter and every with some ternary logic to determine if the filter value is empty to get all.

var users = [{
    name: 'John',
    email: 'johnson@mail.com',
    age: 25,
    address: 'USA'
  },
  {
    name: 'Tom',
    email: 'tom@mail.com',
    age: 35,
    address: 'England'
  },
  {
    name: 'Mark',
    email: 'mark@mail.com',
    age: 28,
    address: 'England'
  }
];

var filter1 = {address: 'England', name: 'Mark'};
var filter2 = {address: 'England', name: ''};

function findResults(input, filterObj){
   return input.filter(
      item => Object.keys(filterObj)
                    .every(r => filterObj[r].length 
                                   ? item[r] == filterObj[r] 
                                   : true)
   )
}

console.log('with address and name', findResults(users,filter1));
console.log('with address only', findResults(users,filter2));
Jamiec
  • 133,658
  • 13
  • 134
  • 193
0

If I understand your question correctly you need following output. If this what you are looking for Array.filter should suffice your use case. Take a look at the code sandbox where I have created a function filterByObj which takes arr, filterObj as arguments and returns given output for { address: "England", name: "" }

enter image description here

Shubham Gupta
  • 2,596
  • 1
  • 8
  • 19
-2

You need you filter for this case.

var filter1 = {
  address: 'England',
  name: 'Mark'
};

var filter2 = {
  address: 'England',
  name: ''
};

var users = [
  {
    name: 'John',
    email: 'johnson@mail.com',
    age: 25,
    address: 'USA'
  },
  {
    name: 'Tom',
    email: 'tom@mail.com',
    age: 35,
    address: 'England'
  },
  {
    name: 'Mark',
    email: 'mark@mail.com',
    age: 28,
    address: 'England'
  }
];

function filterUser(arr, obj) {
  return arr.filter(function(item) {
    return (
      (obj.address === '' || item.address === obj.address) &&
      (obj.name === '' || item.name === obj.name)
    );
  });
}

console.log(filterUser(users, filter1));
console.log(filterUser(users, filter2));