Consider an array of N items.
data = [
{"source":"post","target":"incident"},
{"source":"incident","target":"analysis"},
{"source":"october","target":"post"},
{"source":"mef","target":"composing"},
{"source":"trend","target":"archive"},
{"source":"object","target":"constructor"},
{"source":"constructor","target":"parameter"}
]
I have a function that creates -based on this data- a matrix of nodes. Let's say:
[[0, 1, 0, 1, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 0]]
This function works fine with a given data. However, I noted that in this specific sources and targets it returns an error. The problem is the word: constructor in it. If I changed for example constructor to constructr, the functions will return the matrix.
I found the problem in this part:
let nodes = {}
data.map(link => {
nodes[link.source] || (nodes[link.source] = 1)
nodes[link.target] || (nodes[link.target] = 1)
})
nodes = d3.keys(nodes)
nodes.sort()
After this process, nodes only contains this data: ["analysis", "archive", "composing", "incident", "mef", "object", "october", "parameter", "post", "trend"] but constructor is missing.
When I try to console some data: this specific node returns this: ƒ Object() { [native code] }.
I fixed this issue converting each word in upper case toUpperCase(). However, I would like to know if there is other alternative to solve this.
Thanks in advance.
Most objects in javascript have a constructor method - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
Thanks to the comment by user2864740 - code that is close to the original in logic - uses .hasOwnProperty - since constructor is inherited, this will be false, until you explicitly assign it
data = [
{"source":"post","target":"incident"},
{"source":"incident","target":"analysis"},
{"source":"october","target":"post"},
{"source":"mef","target":"composing"},
{"source":"trend","target":"archive"},
{"source":"object","target":"constructor"},
{"source":"constructor","target":"parameter"}
]
let nodes = {};
data.forEach(link => {
nodes.hasOwnProperty(link.source) || (nodes[link.source] = 1);
nodes.hasOwnProperty(link.target) || (nodes[link.target] = 1);
})
nodes = Object.keys(nodes)
nodes.sort()
console.log(nodes.join());
Or, you could use Object.create(null);
Please read the caveats when using Object.create(null) in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Custom_and_Null_objects
As long as you know the limitations, you shouldn't have any issues
data = [
{"source":"post","target":"incident"},
{"source":"incident","target":"analysis"},
{"source":"october","target":"post"},
{"source":"mef","target":"composing"},
{"source":"trend","target":"archive"},
{"source":"object","target":"constructor"},
{"source":"constructor","target":"parameter"}
]
let nodes = Object.create(null);
data.forEach(link => {
nodes[link.source] || (nodes[link.source] = 1)
nodes[link.target] || (nodes[link.target] = 1)
})
nodes = Object.keys(nodes)
nodes.sort()
console.log(nodes.join());
Of course, the reason why your code fails is because nodes already has constructor property (and many others)
so
nodes[link.target] || (nodes[link.target] = 1)
is
nodes.constructor || (nodes.constructor = 1)
and since nodes.constructor is truthy it's never "overwritten" with value 1
you could simply do
nodes[link.source] = 1;
nodes[link.target] = 1;
with identical results, there's actually no need to do this:
nodes[link.source] || (nodes[link.source] = 1);
nodes[link.target] || (nodes[link.target] = 1);
see the following snippet:
data = [
{"source":"post","target":"incident"},
{"source":"incident","target":"analysis"},
{"source":"october","target":"post"},
{"source":"mef","target":"composing"},
{"source":"trend","target":"archive"},
{"source":"object","target":"constructor"},
{"source":"constructor","target":"parameter"}
]
let nodes = {};
data.forEach(link => {
nodes[link.source] = 1;
nodes[link.target] = 1;
})
nodes = Object.keys(nodes)
nodes.sort()
console.log(nodes.join());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With