0

I am having issue with my recursive function getPath, as it is returning an empty array, when it should be returning an array that looks something like this:

['main', 'children', 'name']

I am not sure if the logic pare is right, as that isn't what the question is about, the question is, why is my array empty? It is pushing data onto the array, but the final result is an empty array.

let dataScope = [{
  "name": "main",
  "location": [":data"]
}, {
  "name": "child",
  "location": ["main", "children"]
}]

function getLocation(key) {
  let val = dataScope.find(i => i.name == key)
  return val ? val.location : []
}

function getPath(items) {
  let path = []
  let item = items.shift()
  if (item) {
    let loc = getLocation(item)
    if (loc.length > 0 && loc.join('.') != ':data') {
      path.push(...getPath(loc))
      console.log('added to array')
    }
  }
  return path
}

console.log(getPath(['child', 'name']))

12
  • 1
    well, your first item fails the test, therefore you never recurse Commented Mar 9, 2018 at 2:49
  • are you sure? added to array is printed out... Commented Mar 9, 2018 at 2:50
  • hmmm, it is too! something else must be wrong then Commented Mar 9, 2018 at 2:51
  • Why not put a console.log(path) before your added to array loc then? Commented Mar 9, 2018 at 2:52
  • @JaromandaX, the first item checked is child, which should not fail Commented Mar 9, 2018 at 2:52

3 Answers 3

1

You don't do anything with loc so, it seems nothing gets pushed to the array

Note: I'm still trying to get to grips with why your original code results in an empty array - however, this code produces the expected result :p

let dataScope = [{
  "name": "main",
  "location": [":data"]
}, {
  "name": "child",
  "location": ["main", "children"]
}]

function getLocation(key) {
  let val = dataScope.find(i => i.name == key);
  return val ? val.location : []
}

function getPath(items, indent = 0) {
  let z = items.join(',');
  console.log(`${' '.repeat(indent)}called with ${z}`);
  let path = [];
  let item = items.shift();
  let loc = [];
  if (item) {
    loc = getLocation(item);
    if (loc.length > 0 && loc.join('.') != ':data') {
      path.push(...getPath(loc.slice(), indent + 4)); // .slice() so loc isn't mutated
      console.log(`${' '.repeat(indent)}${z} has path [${path.join(',')}]`);
    }
    path.push(...loc); // add loc to the path - comment this out to see the difference
  }
  console.log(`${' '.repeat(indent)}${z} returns [${path.join(',')}]`);
  return path
}

console.log(`[${getPath(['child', 'name'])}]`)

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

5 Comments

I changed yours a little by just pushing loc to the array then calling getPath(loc) afterwards without pushing that to the array, and that seems to work.
why?? doesn't that produce a different result order? (I don't really know what you changed though)
I changed path.push(...getPath(loc)) to path.push(...loc);getPath(loc)
won't that result in [main,children,:data] - not what you expected, right?
It seems to work when I do that. I also need to push what is left of the items array to the end of the path[], which I did after the if, and I am now getting [main,children,name], which looks closer to what I want for the final result. (now that I can visualize the output :))
0

First youre passing an array of names to getPath but then later youre passing the location array. Which one should it be? Logic needs tweaking. And also there's nothing in the dataset using the value "name" so your test is incorrect as well.

Comments

0

Its because you're doing recursion sending dataScope location but you implemented getPath expecting dataScope keys:

let dataScope = [{
  "name": "main",
  "location": [":data"]
}, {
  "name": "child",
  "location": ["main", "children"]
}]

function getLocation(key) {
  let val = dataScope.find(i => i.name == key)
  return val ? val.location : []
}

function getPath(keys) { // changing items name to keys for clarification
  let path = []
  let key = keys.shift()
  if (key) {
    let loc = getLocation(key);
    if (loc.length > 0 && loc.join('.') != ':data') {
      path.push(...loc) // push locs into array
      getPath(keys) // call getPath with remaining keys
      console.log('added to array')
    }
  }
  return path
}

console.log(getPath(['child', 'main']))

You will not have :data into your path result because of this statement: loc.join('.') != ':data'. If you remove it you will get your expected output.

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.