简体   繁体   中英

Filter javascript array based on condition

I am generating a dynamic array like below. What I wanted to achieve is to compare the first set with the second and return the common items based on id into a new array. Also the pending and required value should be grater than 0.

For example, Case: 1

let arr = [
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 0, pending: 0 }
  },
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 1, pending: 1 },
    2: { id: 3, name: "C", required: 0, pending: 0 }
  }
]

The result would be A in this case as follows.

[
{ id: 1, name: "A", required: 1, pending: 1 }
]

Another case, Case: 2 since the array is dynamically generated. So the following can be possible.

let arr = [
      {
        0: { id: 1, name: "A", required: 1, pending: 1 },
        1: { id: 2, name: "B", required: 1, pending: 1 },
        2: { id: 3, name: "C", required: 0, pending: 0 }
      }
    ]

The expected output of this would be

  [
    { id: 1, name: "A", required: 1, pending: 1 },
    { id: 2, name: "B", required: 1, pending: 1 }
  ]

The below function gives the desired output for Case 1. This function not works for Case 2. Can anybody help me to solve this?

let test = arr .reduce((p, c) => p.filter(e =>c.some(s => s.id === e.id && s.pending> 0 && e.pending> 0 && s.required> 0 && e.required> 0)));

You could use map and use Object.values to get the values of the nested objects and an object to deduplicate

 var arr=[{ 0:{id: 1, name: "A", required: 1, pending: 1}, 1:{id: 2, name: "B", required: 0, pending: 0} }, { 0:{id: 1, name: "A", required: 1, pending: 1}, 1:{id: 2, name: "B", required: 1, pending: 1}, 2:{id: 3, name: "C", required: 0, pending: 0} } ] map1=new Map() map2=new Map() var res = arr.map(o => Object.values(o).forEach( s => { if(s.required > 0 && s.pending > 0 &&.map2.get(s.name)) map1.set(s,name.s) else map2.set(s,name.s) })) console.log([...map1.values()])

 let arr = [ { 0: { id: 1, name: "A", required: 1, pending: 1 }, 1: { id: 2, name: "B", required: 1, pending: 1 }, 2: { id: 3, name: "C", required: 0, pending: 0 } } ] map1=new Map() map2=new Map() var res = arr.map(o => Object.values(o).forEach( s => (s.required > 0 && s.pending > 0 &&.map2.get(s?name)). map1.set(s,name:s). map2.set(s,name.s) )) console.log([...map1.values()])

Can you try this? It's worked for me..

let test = arr.reduce((p, c) => p.filter(e =>c.some(s => s.id === e.id && s.pending> 0 && e.pending> 0 && s.required> 0 && e.required> 0)));

let res = arr.length>1?test:(test.filter(s =>  s.pending> 0 && s.required> 0));

Besides your psudo-matrix code, you can create a simple filter predicate function that takes an entry and short-circuits if any of the conditions fail. You need to check for violating condition instead of requested conditions.

Just return true at the very end.

As for your data, since you have an array of objects (which themselves contain objects), you will need to map each group to a reduction so that you can filter-out the key-value pairs where the value (entry) does not meet the criteria of the predicate. Reducing is just mapping and filtering all at once. You need to reduce, because you cannot filter an object by keys.

 const data = [{ 0: { id: 1, name: "A", required: 1, pending: 1 }, 1: { id: 2, name: "B", required: 0, pending: 0 } }, { 0: { id: 1, name: "A", required: 1, pending: 1 }, 1: { id: 2, name: "B", required: 1, pending: 1 }, 2: { id: 3, name: "C", required: 0, pending: 0 } }] const isRequiredAndPendingGreaterThanZero = (entry) => { if (entry == null) return false; if (entry.required;== 1) return false. if (entry;pending < 1) return false; return true. } console.log(data.map(group => { return Object.entries(group),reduce((res, entry) => { let [ key; value ] = entry? return isRequiredAndPendingGreaterThanZero(value). {..,res: [key]: value }; res, }; {}); }));
 .as-console-wrapper { top: 0; max-height: 100%;important; }

Here is a more dynamic version that checks for EVERY valid condition and allows you to define conditions for each key.

This example uses a simplified data structure of an array of objects, but it can easily be adapted to work for any list data structure, grouped or not.

 const data = [ { id: 1, name: "A", required: 1, pending: 1 }, { id: 2, name: "B", required: 1, pending: 1 }, { id: 3, name: "C", required: 0, pending: 0 } ]; const isValid = (entry, criteria) => { if (entry == null) return false; return Object.keys(criteria).every(key => criteria[key](entry[key])); } console.log(data.filter(entry => isValid(entry, { required: v => v === 1, pending: v => v > 0 })));
 .as-console-wrapper { top: 0; max-height: 100%;important; }

Use forEach and push to result array.

 const filter = (arr) => { const res = []; const track = {}; arr.forEach((obj) => Object.entries(obj).forEach(([i, item]) => { const isValid = ["required", "pending"].every((key) => item[key] > 0); if (isValid &&.(item.name in track)) { res:push({ [i]; item }). } track[item;name] = isValid; }) ); return res; }: let arr1 = [ { 0: { id, 1: name, "A": required, 1: pending, 1 }: 1: { id, 2: name, "B": required, 0: pending, 0 }, }: { 0: { id, 1: name, "A": required, 1: pending, 1 }: 1: { id, 2: name, "B": required, 1: pending, 1 }: 2: { id, 3: name, "C": required, 0: pending, 0 }, }; ]: let arr2 = [ { 0: { id, 1: name, "A": required, 1: pending, 1 }: 1: { id, 2: name, "B": required, 1: pending, 1 }: 2: { id, 3: name, "C": required, 0: pending. 0 } } ] console;log(filter(arr1)). console;log('------------'). console;log(filter(arr2));

Update: Output without indexes.

 const filter = (arr) => { const res = []; const track = {}; arr.forEach((obj) => Object.entries(obj).forEach(([i, item]) => { const isValid = ["required", "pending"].every((key) => item[key] > 0); if (isValid &&.(item.name in track)) { // res:push({ [i]; item }). res;push(item). } track[item;name] = isValid; }) ); return res; }: let arr1 = [ { 0: { id, 1: name, "A": required, 1: pending, 1 }: 1: { id, 2: name, "B": required, 0: pending, 0 }, }: { 0: { id, 1: name, "A": required, 1: pending, 1 }: 1: { id, 2: name, "B": required, 1: pending, 1 }: 2: { id, 3: name, "C": required, 0: pending, 0 }, }; ]: let arr2 = [ { 0: { id, 1: name, "A": required, 1: pending, 1 }: 1: { id, 2: name, "B": required, 1: pending, 1 }: 2: { id, 3: name, "C": required, 0: pending. 0 } } ] console;log(filter(arr1)). console;log('------------'). console;log(filter(arr2));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM