Sam Toorchi
Sam Toorchi

Reputation: 143

javascript remove element from object array if key not exist

I have to compare 2 arrays by values for the keys. If "target" or "source" from the "links" array are not one of the "id"s from the "nodes" array, the corresponding array must be removed from "links".

from:

{
    "nodes":[
        {
            "id": b,
            "year": 3
        },
        {
            "id": c,
            "year": 1
        },
                {
            "id": d,
            "year": 2
        }
    ],
    "links":[
        {
            "source": a,
            "target": b
        },
        {
            "source": a,
            "target": c
        },
        {
            "source": b,
            "target": a
        }
        {
            "source": c,
            "target": d
        }
    ]
}

result:

{
    "nodes":[
        {
            "id": b,
            "year": 3
        },
        {
            "id": c,
            "year": 1
        },
                {
            "id": d,
            "year": 2
        }
    ],
    "links":[
        {
            "source": c,
            "target": d
        }
    ]
}

it would be very nice if someone could help me solve this problem with javascript.

Upvotes: 0

Views: 1117

Answers (4)

Sudheesh S Krishna
Sudheesh S Krishna

Reputation: 39

links.filter((link)=>{
    let sourceMatch = nodes.find((node)=>{
        return node.id == link.source;
    });

    let targetMatch = nodes.find((node)=>{
        return node.id == link.target;
    });

    return sourceMatch && targetMatch;
});

Upvotes: 0

user2560539
user2560539

Reputation:

Another approach using double forEach and splice.

const obj = JSON.parse('{"nodes":[{"id": "b","year": 3},{"id": "c","year": 1},{"id": "d","year": 2}],"links":[{"source": "a","target": "b"},{"source": "a","target": "c"},{"source": "b","target": "a"},{"source": "c","target": "d"}]}');

obj.nodes.forEach((v,k) => {
obj.links.forEach((q,p) => {
if(v.id !== q.target || v.id !== q.source) {
  obj.links.splice(0,p);
}
});
});
console.log(obj);
;

Upvotes: 0

Alf Nielsen
Alf Nielsen

Reputation: 1382

A reduce method can do this for you:

let nodes = [{
      "id": 'b',
      "year": 3
   },
   {
      "id": 'c',
      "year": 1
   },
         {
      "id": 'd',
      "year": 2
   }
];
let links = [
   {
      "source": 'a',
      "target": 'b'
   },
   {
      "source": 'a',
      "target": 'c'
   },
   {
      "source": 'b',
      "target": 'a'
   },
   {
      "source": 'c',
      "target": 'd'
   }
];


const filteredLinks = links.reduce((p,c,i) => {
   if(
      nodes.some(x => x.id===c.source) 
      && 
      nodes.some(x => x.id===c.target)
   )
   {
      p.push(c) 
   }; 
   return p  
},[]);

console.log(filteredLinks)

Upvotes: 1

first create a set with the ids of nodes

const ids = nodes.map(node => node.id);
const idSet = new Set(ids);

then filter the links array like this:

const filteredLinks = links.filter(link => idSet.has(link.target) && idSet.has(link.source))

then the response will be

return { nodes, links: filteredLinks }

Upvotes: 2

Related Questions