0

I have a list of object that i want to filter by 3 condition: name, role, branch

list = [{​​​​
    "userName": "name1",
    "roleArray": [
        "role1",
        "role2"
    ],
    "branchArray": [
        "branch1",
        "branch2",
        "branch3"
    ]
}​​​​,
{​​​​
    "userName": "name2",
    "roleArray": [
        "role2",
        "role3"
    ],
    "branchArray": [
        "branch3",
        "branch4",
        "branch5"
    ]
}​​​​,
{​​​​
    "userName": "name3",
    "roleArray": [
        "role1",
        "role3"
    ],
    "branchArray": [
        "branch1",
        "branch2",
        "branch4"
    ]
}];
filter_name = "" ; //can be empty
filter_role = ["role1","role3"]; // can be empty
filter_branch = ["branch1","branch5"] //can be empty

How to filter with 3 condition above In the case all condition empty, return the original list

Thank you and have a nice day

AbsoluteBeginner
  • 2,160
  • 3
  • 11
  • 21
  • Are _all_ conditions in one array to be fulfilled (logical "and") or is it enough if _at least one_ of them is fulfilled (logical "or") by any object in the `list` array? – Carsten Massmann Aug 19 '21 at 02:58
  • One condition is enough to filter the list, they can be empty or have value, if multiple condition the filter will be condition1 & condion2 & condition 3 – Tuan Do Huu Aug 19 '21 at 04:25

2 Answers2

0

Your list variable needs to be an array, so I've converted it accordingly.

You could try to fit this into a one liner, but I've separated it for better modularity and readability:

list =[ {
    "userName": "name1",
    "roleArray": [
        "role1",
        "role2"
    ],
    "branchArray": [
        "branch1",
        "branch2",
        "branch3"
    ]
},
{
    "userName": "name2",
    "roleArray": [
        "role2",
        "role3"
    ],
    "branchArray": [
        "branch3",
        "branch4",
        "branch5"
    ]
},
{
    "userName": "name3",
    "roleArray": [
        "role1",
        "role3"
    ],
    "branchArray": [
        "branch1",
        "branch2",
        "branch4"
    ]
}];
filter_name = "name3" ; //can be empty
filter_role = ["role1","role3"]; // can be empty
filter_branch = ["branch1","branch5"] //can be empty

const result = list.filter( u => !u.userName || u.userName === filter_name)
                   .filter( u => !u.roleArray.length || u.roleArray.some( v => filter_role.includes(v)))
                   .filter( u => !u.branchArray.length || u.branchArray.some( v => filter_branch.includes(v)))
                   
console.log (result)
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
tsamridh86
  • 1,480
  • 11
  • 23
  • I have try your solution but when one or all the filter is empty i want to return the list by condition too. for example if filter_name = "name3" and filter_role = filter_branch = [ ] the result should be the object with name = "name3" – Tuan Do Huu Aug 19 '21 at 04:13
  • You could try something like : `.filter( u => { if f( ilter_role.length ==0 ) return true, else u.roleArray.some( v => filter_role.includes(v)) })` – tsamridh86 Aug 19 '21 at 04:56
0

First, I adjusted the type of your list object to array, then I used the filter technology to filter your three conditions, and quickly and easily wrote a query UI, you can click the Run code snippet button below to see the query results

const list = [{
    "userName": "name1",
    "roleArray": ["role1", "role2"],
    "branchArray": ["branch1", "branch2", "branch3"]
}, {
    "userName": "name2",
    "roleArray": ["role2", "role3"],
    "branchArray": ["branch3", "branch4", "branch5"]
}, {
    "userName": "name3",
    "roleArray": ["role1", "role3"],
    "branchArray": ["branch1", "branch2", "branch4"]
}];

$('input[type=button]').on('click', function() {
  const data = Object.fromEntries(new FormData($('form')[0]).entries());
  const result = list.filter(e => {
      const condition1 = data.name == '' ? true : e.userName == data.name;
      const condition2 = data.role == '' ? true : e.roleArray.includes(data.role);
      const condition3 = data.branch == '' ? true : e.branchArray.includes(data.branch);
      return condition1 && condition2 && condition3;
  });
  $('.output').html(result.length == 0 ? $('<p>Empty</p>') : JSON.stringify(result, undefined, 2));
});
.wrap{
  display: flex;
}

.output{
  margin-left:50px;
  border-width:3px;
  border-style:dashed;
  border-color:#FFAC55;
  padding:5px;
  min-width: 150px;
  min-height: 130px;
}
.output p{
  line-height: 100px;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrap">
  <div>
    <form>
      <label for="name">Name:</label><br>
      <input type="text" id="name" name="name"><br>
      <label for="role">Role:</label><br>
      <input type="text" id="role" name="role"> <br>
      <label for="branch">Branch:</label><br>
      <input type="text" id="branch" name="branch"><br><br>
      <input type="button" value="Search">
    </form>
  </div>
  <div>
    <pre class="output">
    </pre>
  </div>
</div>
Ian
  • 1,198
  • 1
  • 5
  • 15
  • Please, the question is about Angular, use `[(ngModel)]`for the inputs and `(click)` to filter – Eliseo Aug 19 '21 at 06:22
  • Hi, thank you for your reminder. I know it is Angular. I just quickly used snippet to build a simple ui simulation. The most important thing is the internal value and filtering method. Both of these points can be used in Angular. – Ian Aug 19 '21 at 06:33
  • I know it, it's only to point out it to avoid Tuan think that it's necessary use jQuery in Angular ;) – Eliseo Aug 19 '21 at 06:47