2

I am using the map (several map getting the necessary elements inside the nested json) function. I am trying to get an output from the Neo4j database according to desired template. During the last map I am building part of desired output having this stored inside variable:

 px.segments.map(function(pathSegment){                                                                                          
  individual_path.push({                          
   "start": pathSegment.start.properties.name,
   "weight": pathSegment.relationship.properties.Weight.low,
   "end": pathSegment.end.properties.name}); 
 })

Then I try:

 console.log(individual_path);

I am getting the following response (as one of the records has null value in the DB):

[ { start: 'A', weight: 0.6180339887498948, end: 'P2' } ]
[]
[ { start: 'P1', weight: 0.6180339887498948, end: 'A' },
  { start: 'A', weight: 0.6180339887498948, end: 'P2' } ]
[ { start: 'P1', weight: 0.6180339887498948, end: 'A' } ]

My question, how can I replace an empty array (while looping over the set of records) with non-empty, like this:

[ { start: 'A', weight: 0.0, end: 'A' } ]

to have at the end something like:

[ { start: 'A', weight: 0.6180339887498948, end: 'P2' } ]
 *[ { start: 'A', weight: 0.0, end: 'A' } ]*
[ { start: 'P1', weight: 0.6180339887498948, end: 'A' },
  { start: 'A', weight: 0.6180339887498948, end: 'P2' } ]
[ { start: 'P1', weight: 0.6180339887498948, end: 'A' } ]

I was not quite clear, I will add the console.log(px); output:

Path {
  start:
   Node {
     identity: Integer { low: 1, high: 0 },
     labels: [ 'concept' ],
     properties: { name: 'A', type: 'string' } },
  end:
   Node {
     identity: Integer { low: 2, high: 0 },
     labels: [ 'concept' ],
     properties: { name: 'P2', type: 'string' } },
  segments:
   [ PathSegment { start: [Object], relationship: [Object], end: [Object] } ],
  length: 1 }
Path {
  start:
   Node {
     identity: Integer { low: 1, high: 0 },
     labels: [ 'concept' ],
     properties: { name: 'A', type: 'string' } },
  end:
   Node {
     identity: Integer { low: 1, high: 0 },
     labels: [ 'concept' ],
     properties: { name: 'A', type: 'string' } },
  segments: [],
  length: 0 }
Path {
  start:
   Node {
     identity: Integer { low: 0, high: 0 },
     labels: [ 'concept' ],
     properties: { name: 'P1', type: 'string' } },
  end:
   Node {
     identity: Integer { low: 2, high: 0 },
     labels: [ 'concept' ],
     properties: { name: 'P2', type: 'string' } },
  segments:
   [ PathSegment { start: [Object], relationship: [Object], end: [Object] },
     PathSegment { start: [Object], relationship: [Object], end: [Object] } ],
  length: 2 }
Path {
  start:
   Node {
     identity: Integer { low: 0, high: 0 },
     labels: [ 'concept' ],
     properties: { name: 'P1', type: 'string' } },
  end:
   Node {
     identity: Integer { low: 1, high: 0 },
     labels: [ 'concept' ],
     properties: { name: 'A', type: 'string' } },
  segments:
   [ PathSegment { start: [Object], relationship: [Object], end: [Object] } ],
  length: 1 }

As you can see one of the blocks has an empty element segment, namely the second path block. What I need is to be able to replace an empty element, with object of the type (start: '', weight: , end:'')

And here is the console.log(px.segments);:

[ PathSegment {
    start: Node { identity: [Object], labels: [Array], properties: [Object] },
    relationship:
     Relationship {
       identity: [Object],
       start: [Object],
       end: [Object],
       type: 'link',
       properties: [Object] },
    end: Node { identity: [Object], labels: [Array], properties: [Object] } } ]
[]
[ PathSegment {
    start: Node { identity: [Object], labels: [Array], properties: [Object] },
    relationship:
     Relationship {
       identity: [Object],
       start: [Object],
       end: [Object],
       type: 'link',
       properties: [Object] },
    end: Node { identity: [Object], labels: [Array], properties: [Object] } },
  PathSegment {
    start: Node { identity: [Object], labels: [Array], properties: [Object] },
    relationship:
     Relationship {
       identity: [Object],
       start: [Object],
       end: [Object],
       type: 'link',
       properties: [Object] },
    end: Node { identity: [Object], labels: [Array], properties: [Object] } } ]
[ PathSegment {
    start: Node { identity: [Object], labels: [Array], properties: [Object] },
    relationship:
     Relationship {
       identity: [Object],
       start: [Object],
       end: [Object],
       type: 'link',
       properties: [Object] },
    end: Node { identity: [Object], labels: [Array], properties: [Object] } } ]
  • Please provide a [mcve] – Code-Apprentice Jun 24 '19 at 16:08
  • On which variable you are doing console.log on? Please mention that – weegee Jun 24 '19 at 16:10
  • sorry, my mistake, already done, I thought it was clear – Artem Nazarenko Jun 24 '19 at 16:12
  • 1
    Note that `map()` already builds a new array. By building `individual_path` yourself and calling `.push()` you are using much more memory than necessary. – Code-Apprentice Jun 24 '19 at 16:15
  • thanks for input, but I am trying to parse the response and then combine different things in a joint output according to a template, I mentioned, that I have a nested object – Artem Nazarenko Jun 24 '19 at 16:18
  • @ArtemNazarenko Check my answer below for one solution. Also Asaf Aviv's answer will work if you are building up a 2D array. – Code-Apprentice Jun 24 '19 at 16:25
  • @Code-Apprentice How can you the return the expected output not in a 2D array ? – Asaf Aviv Jun 24 '19 at 16:29
  • @AsafAviv The code given by the OP only shows building an array of objects called `individual_path`. It does **not** show how this array is used. I think the assumption we both make that it is added to another array to build a 2D array is reasonable, but this is still just an assumption. Note that the output is from logging each of these arrays as they are build, not from logging a 2D array. There are no commas after each array in the output. – Code-Apprentice Jun 24 '19 at 16:31
  • @Code-Apprentice I agree. we cant see how `pathSegmet` looks like in the `map` function too, he says it can be an empty array but try to push an `object` to `individual_path` – Asaf Aviv Jun 24 '19 at 16:34
  • 2
    @ArtemNazarenko do `console.log(px.segments)` put the things here. Make it easier for everyone to solve your problem by including all of the possible information that can be a function of your outcome see [mcve] – weegee Jun 24 '19 at 16:38

3 Answers3

1

Put this code where you are doing console.log().

if (!individual_path.length){ 
   individual_path.push({ start: 'A', weight: 0.0, end: 'A' });
}

If by doing console.log() gives an empty array [] then it's length == 0 and we know 0 == false all of this is true.

Also, use .map when you are returning an array. For now, forEach seems to do the job.

px.segments.forEach((pathSegment) => {                                                                                          
  individual_path.push({                          
   "start": pathSegment.start.properties.name,
   "weight": pathSegment.relationship.properties.Weight.low,
   "end": pathSegment.end.properties.name
   }); 
});

Live example of what I meant

let individual_path = [];
if (!individual_path.length) {
   individual_path.push({ start: 'A', weight: 0.0, end: 'A' });
}
console.log(individual_path) // should give that object

So your code becomes

if (!individual_path.length){ 
   individual_path.push({ start: 'A', weight: 0.0, end: 'A' });
}
console.log(individual_path);
weegee
  • 3,256
  • 2
  • 18
  • 32
-1

First, I suggest taking advantage of the new array map() already builds:

var individual_path = px.segments.map(function(pathSegment){                                                                                          
  return {                          
   "start": pathSegment.start.properties.name,
   "weight": pathSegment.relationship.properties.Weight.low,
   "end": pathSegment.end.properties.name};
 };

Now if this is empty, just replace it with the desired array:

if (individual_path.length === 0) {
    individual_path = [ { start: 'A', weight: 0.0, end: 'A' } ];
}
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
-1
const individual_path = px.segments.length
  ? segments.map(pathSegment => ({
      start: pathSegment.start.properties.name,
      weight: pathSegment.relationship.properties.Weight.low,
      end: pathSegment.end.properties.name,
    }))
  : [{ start: 'A', weight: 0.0, end: 'A' }];
Asaf Aviv
  • 11,279
  • 1
  • 28
  • 45
  • @weegee That comment doesn't negate this answer which directly addresses the quesiton. – Code-Apprentice Jun 24 '19 at 16:22
  • Yes @Code-Apprentice but map returns an array and he is using it in place of forEach. This is why the downvote. Else it directly addresses the question. I didn't close it as Not an answer – weegee Jun 24 '19 at 16:24
  • 1
    @weegee The OP is using map, That's why i also used map. he doesn't state anywhere that he doesn't want to mutate the array and we clearly can't see how the entire object looks like. – Asaf Aviv Jun 24 '19 at 16:26