Search code examples
javascriptarraysd3.jsd3-force-directed

derive array of unique property values from an array of objects


So, I've got an array of link objects from d3

nodelinks
(6) […]
0: Object { index: 1, source: {…}, target: {…} }
1: Object { index: 5, source: {…}, target: {…} }
2: Object { index: 8, source: {…}, target: {…} }
3: Object { index: 9, source: {…}, target: {…} }
4: Object { index: 10, source: {…}, target: {…} }
5: Object { index: 21, source: {…}, target: {…} }
length: 6
<prototype>: Array []

And I want to derive a new array from it containing unique nodes, both source and target. I mangaged to do it like this:

_nodes = []
nodelinks.forEach(x => {
  if (!(x.target in _nodes)){_nodes.push(x.target)};
  if (!(x.source in _nodes)){_nodes.push(x.source)};
});

new Set(_nodes).forEach(x => d3.select(`#${x.id}`).classed('active', true))

But really! There must be a better way: some clever javascripty idiom with map() or filter() or something, yes? Or maybe d3 has some native array method? In python I'd have used a list comprehension. I must be missing something obvious.

any hints?


Solution

  • Hah! I knew I was missing something obvious: Array().flat() Very useful: instead of iterating over the array of objects nodelinks and pushing to a new array, I can just use map() like this:

    new Set(nodelinks.map(x => [x.source, x.target]).flat())
    

    Sorry for the noise, but maybe my naive flailing around can be instructive.