Q:

Find element in array and return parent

I'm having an issue trying to get parent element of found element in array.
This is my array for example:
const arr = [
  {
    name: 'first level',
    selected: true,
    subItems: [
      {
        name: 'second level 1',
        selected: false,
        subItems: [],
      },
      {
        name: 'second level 2',
        selected: true,
        subItems: [
          {
            name: 'third level 1',
            selected: false,
            subItems: [],
          },
          {
            name: 'third level 2',
            selected: false,
            subItems: [],
          },
          {
            name: 'third level 3',
            selected: false,
            subItems: [],
          }
        ]
      },
      {
        name: 'second level 3',
        selected: false,
        subItems: [
          {
            name: 'third level 4',
            selected: false,
            subItems: []
          }
        ]
      }
    ]
  }
];

So basically if key selected is true I would like to return it's parent element. Now I don't know how deep can this array be, so I have taken recursive approach to the problem.
const getParent = (items, parentCat = null) => {
    if (items && items.length > 0) {
        const selectedCat = items.find(item => item.selected === true);
        if (selectedCat && selectedCat.subItems.length > 0) {
          return getParent(selectedCat.subItems, selectedCat);
        }
        return parentCat;
    }
};

const parent = getParent(arr);

But the code will only work in some cases when there are not subItems for the selected item. I would like to get parent item of deepest selected element.
EDIT: If any element has selected true, also it's parent will have true, also there will always be just one selected element per level.

A:

The problem is that within the recursion, if none of the items are selected, you must return the parent's parent. You can accomplish that by returning null within the deepest recursion, and let the caller handle it as the stack unwinds.
const getParent = (items, parent = null) => {
    const selectedItem = items.find(item => item.selected === true);
    if (selectedItem) {
        // if there was a deeper parent, return that
        // otherwise return my own parent
        return getParent(selectedItem.subItems, selectedItem) || parent;
    } else {
        return null;
    }
};

const arr = [
  {
    name: 'first level',
    selected: true,
    subItems: [
      {
        name: 'second level 1',
        selected: false,
        subItems: [],
      },
      {
        name: 'second level 2',
        selected: true,
        subItems: [
          {
            name: 'third level 1',
            selected: false,
            subItems: [],
          },
          {
            name: 'third level 2',
            selected: false,
            subItems: [],
          },
          {
            name: 'third level 3',
            selected: false,
            subItems: [],
          }
        ]
      },
      {
        name: 'second level 3',
        selected: false,
        subItems: [
          {
            name: 'third level 4',
            selected: false,
            subItems: []
          }
        ]
      }
    ]
  }
];

const getParent = (items, parent = null) => {
    const selectedItem = items.find(item => item.selected === true);
    if (selectedItem) {
        return getParent(selectedItem.subItems, selectedItem) || parent;
    } else {
        return null;
    }
};

console.log(getParent(arr));

