0

I need to obtain the Modules, with those postings whose locality equals to "Vienna", I am not being able to eliminate those that do not pass the validation.

This is the json.

const json = [
   {
      "title":"Module A",
      "postings":[
         {"name": "1", "categories":{"location":"Viena"},},
         {"name": "2", "categories":{"location":"Paris"},},
         {"name": "3", "categories":{"location":"Viena"},},
        ]
   },
   {
      "title":"Module B",
      "postings":[
         {"name": "1", "categories":{"location":"Madrid"},},
         {"name": "3", "categories":{"location":"Paris"},},
        ]
   },
   {
      "title":"Module C",
      "postings":[
         {"name": "1", "categories":{"location":"Madrid"},},
         {"name": "2", "categories":{"location":"Viena"},},
        ]
   },  
];

Expected result

[
  {
      "title":"Module A",
      "postings":[
         {"name": "1", "categories":{"location":"Viena"},},
         {"name": "3", "categories":{"location":"Viena"},},
        ]
   },
   {
      "title":"Module C",
      "postings":[
         {"name": "2", "categories":{"location":"Viena"},},
        ]
   },  
];

This is what I'm trying

const result = json
.filter(module => module.postings
.filter(posting => posting.categories.location === 'Viena').length);

Actual Result

I am not being able to remove those postings that do not meet the condition.

wlh
  • 3,426
  • 1
  • 16
  • 32
santi
  • 53
  • 1
  • 2

2 Answers2

0

filter needs to return a truthy value - so you should use some inside it not another filter

const json = [
   {
      "title":"Module A",
      "postings":[
         {"name": "1", "categories":{"location":"Viena"},},
         {"name": "2", "categories":{"location":"Paris"},},
         {"name": "3", "categories":{"location":"Viena"},},
        ]
   },
   {
      "title":"Module B",
      "postings":[
         {"name": "1", "categories":{"location":"Madrid"},},
         {"name": "3", "categories":{"location":"Paris"},},
        ]
   },
   {
      "title":"Module C",
      "postings":[
         {"name": "1", "categories":{"location":"Madrid"},},
         {"name": "2", "categories":{"location":"Viena"},},
        ]
   },  
];

var result = json.filter(x => x.postings.some(p => p.categories.location == "Viena"));

console.log(result);

If you then want to also filter the postings it's a little bit more work

const json = [
   {
      "title":"Module A",
      "postings":[
         {"name": "1", "categories":{"location":"Viena"},},
         {"name": "2", "categories":{"location":"Paris"},},
         {"name": "3", "categories":{"location":"Viena"},},
        ]
   },
   {
      "title":"Module B",
      "postings":[
         {"name": "1", "categories":{"location":"Madrid"},},
         {"name": "3", "categories":{"location":"Paris"},},
        ]
   },
   {
      "title":"Module C",
      "postings":[
         {"name": "1", "categories":{"location":"Madrid"},},
         {"name": "2", "categories":{"location":"Viena"},},
        ]
   },  
];

const filterLocation = loc =>  p => p.categories.location == loc;

const isViena = filterLocation("Viena");

const result = json.filter(x => x.postings.some(isViena))
                 .map(x => ({
                             ...x,
                             postings: x.postings.filter(isViena)
                  }));

console.log(result);
Jamiec
  • 133,658
  • 13
  • 134
  • 193
-1

I found a quick solution with the help of the reduce function.

const json = [
   {
      "title":"Module A",
      "postings":[
         {"name": "1", "categories":{"location":"Viena"},},
         {"name": "2", "categories":{"location":"Paris"},},
         {"name": "3", "categories":{"location":"Viena"},},
        ]
   },
   {
      "title":"Module B",
      "postings":[
         {"name": "1", "categories":{"location":"Madrid"},},
         {"name": "3", "categories":{"location":"Paris"},},
        ]
   },
   {
      "title":"Module C",
      "postings":[
         {"name": "1", "categories":{"location":"Madrid"},},
         {"name": "2", "categories":{"location":"Viena"},},
        ]
   },  
];
let result = json.reduce((acc, curr) => {
    curr.postings = curr.postings.filter(e => e.categories.location == "Viena")
    if(curr.postings.length > 0)
        acc.push(curr);
    return acc;
}, []);

console.log(result);

If you want to learn more about that function you can find it here: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

EDIT:

If you want to get the best performance you should consider using my solution, since with the help of reduce you have a complexity of O(n). With the solution what @Jamiec suggested you get a complexity of O(2n) since you filter and map over it again including the cost of memory since you are creating an additional array.

MertDalbudak
  • 129
  • 8
  • Thanks! @MertDalbudak and @Jamiec! both solutions work! Thank you very much !! – santi Mar 22 '21 at 15:50
  • [O(n) and O(2n) are pretty much identical](https://stackoverflow.com/questions/25777714/which-algorithm-is-faster-on-or-o2n#:~:text=Theoretically%20O(N)%20and%20O,of%20both%20will%20be%20identical.) – Jamiec Mar 22 '21 at 15:53
  • No worries you're welcome. You can gain quiet a bit of compute power and memory if you are using `reduce` when you are handling big chunks of data. This comes in handy if you are doing such things in the backend with node.js. – MertDalbudak Mar 22 '21 at 15:55