2

I'm working on recursive functions.

I must push all objects that have the key "data: true" in an array. The console.log in the middle of my function gives me all those objects in separate arrays.

But I can't return an array with the objects at the end. What am I doing wrong? Thanks

const entries = {
  root: {
    data: true,
    key: "root",
    text: "some text"
  },
  test: {
    one: {
      two: {
        data: true,
        key: "test.one.two",
        text: "some text.again"
      },
      three: {
        data: true,
        key: "test.one.three",
        text: "some.more.text"
      }
    },
    other: {
      data: true,
      key: "test3",
      text: "sometext.text"
    }
  },
  a: {
    b: {
      data: true,
      key: "a.b",
      text: "a.b.text"
    },
    c: {
      d: {
        data: true,
        key: "a.c.d",
        text: "some.a.c.d"
      }
    }
  }
};


function recursiveFunc(data) {
  let tab = [];
  for (let property in data) {
    if (data.hasOwnProperty(property)) {
      if (data[property].data === true) {
        tab.push(data[property]);
        console.log("t", tab);
      } else {
        recursiveFunc(data[property])
      }
    }
  }
  return tab
}

console.log(recursiveFunc(entries));

5
  • You don't return anything from nested recursiveFunc call. Commented Nov 22, 2018 at 10:47
  • 2
    You are never using the result of the recursive calls. Just assign it to something and push it to the original array (or concat it, or whatever): jsfiddle.net/aco2qryn Commented Nov 22, 2018 at 10:49
  • Thanks a lot briosheje, it works now. I had tried something like this but forgot the spread operator. Commented Nov 22, 2018 at 10:55
  • None of the answers corrected the infinite recursion when data is false. Commented Nov 22, 2018 at 11:00
  • @Zim that's not true, my fiddle above works with false as a parameter as well. There is no infinite recursion in that case. Commented Nov 22, 2018 at 11:15

3 Answers 3

7

Add tab.concat() on the recursive call for join the items returned by the recursive fn.

const entries = {
  root: {
    data: true,
    key: "root",
    text: "some text"
  },
  test: {
    one: {
      two: {
        data: true,
        key: "test.one.two",
        text: "some text.again"
      },
      three: {
        data: true,
        key: "test.one.three",
        text: "some.more.text"
      }
    },
    other: {
      data: true,
      key: "test3",
      text: "sometext.text"
    }
  },
  a: {
    b: {
      data: true,
      key: "a.b",
      text: "a.b.text"
    },
    c: {
      d: {
        data: true,
        key: "a.c.d",
        text: "some.a.c.d"
      }
    }
  }
};


function recursiveFunc(data) {
  let tab = [];
  for (let property in data) {
    if (data.hasOwnProperty(property)) {
      if (data[property].data === true) {
        tab.push(data[property]);
        console.log("t", tab);
      } else { 
        tab = tab.concat(recursiveFunc(data[property]));
      }
    } 
  } 
  return tab
}
console.log(recursiveFunc(entries));

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

1 Comment

Infinite recursion when there is a data = false. See corrected answer: stackoverflow.com/a/53429407/2898738
1

You can pass an array as second argument that will act as an accumulator.

Plus, I fixed your function that loops infinitely when data = false:

function recursiveFunc(data, acc) {
  for (let property in data) {
    if (data.hasOwnProperty(property) && typeof data[property] === "object") {

      var current = data[property];

      if (current.data === true) {
        acc.push(current);
      } else {
        recursiveFunc(current, acc)
      }

    }
  }
}

Usage:

var results = [];
recursiveFunc(entries, results);
console.log(results);

Comments

0

You could use a global variable.

const entries = { ... };


var tab = [];

function getTab(data) {
    tab = [];
    recursiveFunc(data);
    return tab;
}
function recursiveFunc(data) {
  for (let property in data) {
    if (data.hasOwnProperty(property) && typeof data[property] === "object") {
      if (data[property].data === true) {
        tab.push(data[property]);
      } else {
        recursiveFunc(data[property])
      }
    }
  }
}

getTab(entries);

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.