Home > database >  Get return value only once after recursive for loop
Get return value only once after recursive for loop

Time:07-07

I have a recursive function to loop trough an array with multiple nested objects and it returns all the most deeply nested children of the objects back. (In other words, it returns only the objects without children).
But the issue that i'm strugling with is that the 'return' is called mutiple times. It returns (in dev console) the array multiple times each time the method is called again.
After some lookup i read that a solution can be to make the function async.
So i tried the below code, but that doesn't work.
The purpose is to loop trough ALL the objects and only return the 'return arr' only when the loop is complety finished.

Any help would really be appreciated. Thx!

async function getChildren(
    obj: Array <Car>,
    arr: Array <Car>,
) {
    for (const subObj of obj) {
        if (
            Object.prototype.hasOwnProperty.call(subObj, 'children') &&
            subObj.children instanceof Array &&
            subObj.children.length > 0
        ) {
            await getChildren(subObj.children, arr);
        } else if (
            Object.prototype.hasOwnProperty.call(subObj, 'code')
        ) {
            arr.push(subObj);
        }
    }
    return arr;
}

CodePudding user response:

Since the function is mutating the arr argument you don't need to return anything.

function getChildren( // not sure why you want to use async so I removed it ...
    obj: Array <Car>,
    arr: Array <Car>,
) {
    for (const subObj of obj) {
        if (
            Object.prototype.hasOwnProperty.call(subObj, 'children') &&
            subObj.children instanceof Array &&
            subObj.children.length > 0
        ) {
            getChildren(subObj.children, arr);
        } else if (
            Object.prototype.hasOwnProperty.call(subObj, 'code')
        ) {
            arr.push(subObj);
        }
    }
}

const data = [/* your objects...*/]
const result = []
getChildren(data, result)
console.log(result)

This example is to illustrate with some sample data (not sure I got right the way your input data is formatted nor the result you want so please correct me is this is too different from your use case)

const data = [{
    children: [{
        children: [{
            code: "azerty"
          },
          {
            code: "jkajsks"
          },
          {
            code: "123"
          }
        ]
      },
      {
        children: [{
            code: "azerty",
            children: [],
          },
          {
            children: [{
              code: "123"
            }]
          },
          {
            code: "123"
          }
        ]
      },
      {
        code: "123"
      },
      {
        code: "abc"
      }
    ]
  },
  {
    code: "123"
  },
  {
    code: "abc"
  }
];

function getChildren(objs, arr) {
  for (const obj of objs) {
    if (obj.children && Array.isArray(obj.children) && obj.children.length > 0) {
      getChildren(obj.children, arr)
    } else if (obj.code) {
      arr.push(obj);
    }
  }
}


const arr = [];

getChildren(data, arr);

console.log(arr)

CodePudding user response:

I assume you want to loop an Array and find out the deeply nested children of each item in this array.(but why you name an array with 'obj'?)
You get multiple return value simply because you called getChildren mutiple times, in you recursion.
Here is my solution based on your code

async function getChildren(obj, arr) {
  const loop = async (loopObj) => {
    loopObj.forEach(async item => {
     if (
         Object.prototype.hasOwnProperty.call(item, 'children') &&
         item.children instanceof Array &&
         item.children.length > 0
        ) {
            await loop(item.children);
        } else if (
            Object.prototype.hasOwnProperty.call(item, 'code')
        ) {
            arr.push(item);
        }
    })
  }
  loop(obj)
  return arr;
}

const OBJ = [
  {
    code: '1',
    children: [
      {
        code: '1.1'
      },
      {
        code: '1.2',
        children: [
          {
            code: '1.2.1',
          },
        ],
      },
    ],
  },
  {
    code: '2',
  },
]
const arr = [];

getChildren(OBJ, arr);

console.log(arr)
  • Related