检查两个数组中的JSON属性

介绍:
我正在使用d3.js库来绘制一个力布局图。 为了让图的更新过程看起来很平常,我想检查一个名为nodes的数组,它包含图中的所有当前nodes和新的incoming json object如果它们具有基于每个node具有的name属性的共享元素)。

示例JSON:

 { "nodes":[ {"name":"Harry Potter", "shortname":"Harry", "id":0}, {"name":"Severus Snape", "shortname":"Severus", "id":1} ], "links":[ {"source":0,"target":1,"relation":"hasTeacher"} ] } 

每个name都是唯一的( 是的,我知道你们中的一些人会争论名字不应该是唯一的原因 ),这个object将是一个函数的input参数。

function:
以下function将所有新的节点推到图上。

 function pushNewElements(json) { var len = json.nodes.length; var difference = json.nodes.filter(function (el) { return isInGraph(el, len); }); difference.forEach(function (node) { nodes.push(node); }); } 

filter()函数
这个函数应该像filter一样工作,并获得nodesjson.nodes数组之间的json.nodes 。 经过多次testing,这是我能想到的最好的。

 function isInGraph(jnode, arrayLength) { //runs vor each entry in json.nodes, 1 of these objects is jnode for (var i = 0; i < nodes.length + arrayLength; i++) { //nodes.length will return 0 at the beginning, //since no object is in the graph yet, the function won't run enough time. try { //We have to try this, because nodes[i] might be out of bound if (jnode.name == nodes[i].name) { return true; } else { return false; } } catch (err) { java.alert(err.message); return false; } } } 

java.alert()是一个在java控制台上打印的自定义函数。

已知的问题:

  • nodes最初将是空的。 所以我不能像往常一样迭代它。 filter应该返回一切。
  • nodesjson.nodes可以包含相同的数据,因此filter不会返回任何内容。
  • json.nodes具有nodes所有数据+一些额外的数据。 对于相同的数据应该返回true,为新的数据false。
  • json.nodesnodes数据less,filter应该返回所有缺less的节点。
  • nodesjson.nodes有一个完全不同的数据集,都应该返回false。

我在问什么?
我知道这是一个很大的任务。 我不是在这里要求任何人解决这个问题。 我只是想知道:

  • 有没有比使用filter()更好的select?
  • 我在我的isInGraph()犯了一个明显的错误吗?
  • 有没有一个好的模式来同时在JavaScript中迭代2个数组?

感谢迄今为止读过的任何人。 如果你觉得我可以改进这个问题,因为它可能不是很好写,或者你(部分)知道如何解决这个问题,请让我知道。

你只犯了很less的错误,总的想法是好的,我纠正/评论的代码:

 var input = { "nodes": [ { "name": "Harry Potter", "shortname": "Harry", "id": 0 }, { "name": "Severus Snape", "shortname": "Severus", "id": 1 } ], "links": [ { "source": 0, "target": 1, "relation": "hasTeacher" } ] }; var nodes = [ // { "name": "Harry Potter", "shortname": "Harry", "id": 0 }, { "name": "Severus Snape", "shortname": "Severus", "id": 1 } ]; function pushNewElements(json) { // you don't need this // var len = json.nodes.length; var difference = json.nodes.filter(function (el) { return !isInGraph(el); // << you want the nodes that are NOT in nodes }); difference.forEach(function (node) { nodes.push(node); }); } function isInGraph(jnode) { for (var i = 0; i < nodes.length; i++) { // if the names match, return true now if (jnode.name == nodes[i].name) { return true; } } // no match found (works with nodes.length == 0) return false; } pushNewElements(input); console.log(nodes); 

这段代码适用于三种明显的情况(元素为0,1或2的nodes )。 现在这里来了lodash单行:

 var _ = require('lodash'); var input = { "nodes": [ { "name": "Harry Potter", "shortname": "Harry", "id": 0 }, { "name": "Severus Snape", "shortname": "Severus", "id": 1 } ], "links": [ { "source": 0, "target": 1, "relation": "hasTeacher" } ] }; var nodes = [ // { "name": "Harry Potter", "shortname": "Harry", "id": 0 }, { "name": "Severus Snape", "shortname": "Severus", "id": 1 } ]; // unionBy returns unique values from two arrays, elements are compared by 'name' nodes = _.unionBy(nodes, json.nodes, 'name'); console.log(nodes); /* output: [ { "name": "Severus Snape", "shortname": "Severus", "id": 1 }, { "name": "Harry Potter", "shortname": "Harry", "id": 0 } ] */