Reputation: 43
Objects are added to nodeArray[]
once they are selected, some of the nodes are connected together and these links are stored in linkArray[]
, each object holds the source ID and the target ID of the node connection.
I need to filter linkArray[]
so that it only returns objects where both source
and target
are in nodeArray[]
.
So far from browsing similar questions i have the following:
var linkArray = [{
"conID": "100",
"source": "10",
"target": "11"
}, {
"conID": "101",
"source": "11",
"target": "12"
}, {
"conID": "102",
"source": "12",
"target": "13"
}, {
"conID": "103",
"source": "13",
"target": "14"
}, {
"conID": "386",
"source": "55",
"target": "32"
}];
var nodeArray = [{"id": "10"}, {"id": "11"}, {"id": "12"}];
function filterArray(array, filter) {
var myArrayFiltered = [];
for (var i = 0; i < array.length; i++) {
for (var j = 0; j < filter.length; j++) {
if (array[i].source === filter[j].id) {
myArrayFiltered.push(array[i]);
}
}
}
return myArrayFiltered;
}
myArrayFiltered = filterArray(linkArray, nodeArray);
document.body.innerHTML = '<pre>'+ JSON.stringify(myArrayFiltered, null, 4) +'</pre>';
I have tried adding to the if statement to include the target ID as well but im not sure i am understanding it correctly.
The result is returning all links with source
matching id
in nodeArray[]
.
[
{
"conID": "100",
"source": "10",
"target": "11"
},
{
"conID": "101",
"source": "11",
"target": "12"
},
{
"conID": "102",
"source": "12",
"target": "13"
}
]
What i need help with is filtering the array so that it only returns objects where both source
and target
ID are in nodeArray[]
.
The desired result after selecting node 10, 11 and 12 will be just 2 objects because node 13 is not in the selection.
[
{
"conID": "100",
"source": "10",
"target": "11"
},
{
"conID": "101",
"source": "11",
"target": "12"
}
]
Hopefully that is clear, Thanks!
Upvotes: 1
Views: 2611
Reputation: 386654
You could use a hash table ids
and test the values against.
var linkArray = [{ conID: "100", source: "10", target: "11" }, { conID: "101", source: "11", target: "12" }, { conID: "102", source: "12", target: "13" }, { conID: "103", source: "13", target: "14" }, { conID: "386", source: "55", target: "32" }],
nodeArray = [{ id: "10" }, { id: "11" }, { id: "12" }],
ids = nodeArray.reduce(function (o, a) {
o[a.id] = true;
return o;
}, Object.create(null)),
result = linkArray.filter(function (a) {
return ids[a.source] && ids[a.target];
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES6 with
Set
for the wanted id
,Array#filter
for getting only the items who match,keys
array with the wanted properties for matching ['source', 'target']
,Array#every
for checking all keys,Set#has
, for checking if the needed key is in the set.var links = [{ conID: "100", source: "10", target: "11" }, { conID: "101", source: "11", target: "12" }, { conID: "102", source: "12", target: "13" }, { conID: "103", source: "13", target: "14" }, { conID: "386", source: "55", target: "32" }],
nodes = [{ id: "10" }, { id: "11" }, { id: "12" }],
keys = ['source', 'target'],
result = links.filter(
(s => a => keys.every(k => s.has(a[k])))(new Set(nodes.map(n => n.id)))
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 6112
You could try this
var linkArray = [{
"conID": "100",
"source": "10",
"target": "11"
}, {
"conID": "101",
"source": "11",
"target": "12"
}, {
"conID": "102",
"source": "12",
"target": "13"
}, {
"conID": "103",
"source": "13",
"target": "14"
}, {
"conID": "386",
"source": "55",
"target": "32"
}];
var nodeArray = [{
"id": "10"
}, {
"id": "11"
}, {
"id": "12"
}];
function filterArray(array, filter) {
// Get all the required ids
var ids = filter.map(function(f) {
return f.id;
});
return array.filter(function(a) {
// Check if both source and target are present in list of ids
return ids.indexOf(a.source) !== -1 && ids.indexOf(a.target) !== -1;
});
}
var myArrayFiltered = filterArray(linkArray, nodeArray);
console.log(myArrayFiltered)
UPDATE
Removed forEach
+ push
and used filter
.
Upvotes: 4
Reputation: 1915
var linkArray = [{
"conID": "100",
"source": "10",
"target": "11"
}, {
"conID": "101",
"source": "11",
"target": "12"
}, {
"conID": "102",
"source": "12",
"target": "13"
}, {
"conID": "103",
"source": "13",
"target": "14"
}, {
"conID": "386",
"source": "55",
"target": "32"
}];
var nodeArray = [{"id": "10"}, {"id": "11"}, {"id": "12"}];
function filterArray(array, filter) {
// map the nodeArray to an array of ids: ["10", "11", "12"]
// could be done outside the function if needed
var ids = nodeArray.map(function(item) {return item.id});
// filter the array only returning itemes that have 'target' and 'source' in ids
return array.filter(function(item) {
return ids.includes(item.target) && ids.includes(item.source)
})
}
myArrayFiltered = filterArray(linkArray, nodeArray);
document.body.innerHTML = '<pre>' + JSON.stringify(myArrayFiltered, null, 4) + '</pre>';
Upvotes: 0
Reputation: 1501
You can convert your nodeArray
to key-value and use that to check both source
and target
of each object in linkArray
var linkArray = [{"conID": "100","source": "10","target": "11"}, {"conID": "101","source": "11","target": "12"}, {"conID": "102", "source": "12", "target": "13"}, {"conID": "103","source": "13","target": "14"}, {"conID": "386","source": "55","target": "32" }];
var nodeArray = [{"id": "10"}, {"id": "11"}, {"id": "12"}];
var nodes ={};
var myArrayFiltered = [];
for(var i =0; i<nodeArray.length;i++){
nodes[nodeArray[i].id] = true;
}
for(var i =0; i<linkArray.length;i++){
if(nodes[linkArray[i].source] && nodes[linkArray[i].target])
myArrayFiltered.push(linkArray[i])
}
console.log(myArrayFiltered)
Upvotes: 0
Reputation: 13943
You can use Array#filter
with the following condition condition
nodeArray.find(n=>n.id === e.source ) && nodeArray.find(n=>n.id === e.target)
The condition uses Array#find
- It will return undefined
if it doesn't find the node with the source or target id
var linkArray = [{"conID": "100","source": "10","target": "11"}, {"conID": "101","source": "11","target": "12"}, {"conID": "102", "source": "12", "target": "13"}, {"conID": "103","source": "13","target": "14"}, {"conID": "386","source": "55","target": "32" }];
var nodeArray = [{"id": "10"}, {"id": "11"}, {"id": "12"}];
var filteredArray = linkArray.filter(e=> nodeArray.find(n=>n.id === e.source ) && nodeArray.find(n=>n.id === e.target));
console.log(filteredArray);
Upvotes: 0