1

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!

5 Answers 5

4

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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,
  • a 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; }

Comments

0

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);

Comments

0

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)

Comments

0

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>';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.