How to optimize two loop
You could use find to get the object which includes the given task in its initialTasks array. This also uses 2 loops. But, it returns when the match is found and is less verbose.


const stagesTasks=[{dataTestID:"stage-0",headerText:"Backlog",initialTasks:["task 1","task 2","task 3"]},{dataTestID:"stage-1",headerText:"To Do",initialTasks:["task 4","task 5","task 6"]},{dataTestID:"stage-2",headerText:"Ongoing",initialTasks:["task 7","task 8"]},{dataTestID:"stage-3",headerText:"Done",initialTasks:["task 9"]}];

function getStageName(task) {
  return stagesTasks.find(s =&gt; s.initialTasks.includes(task))?.dataTestID
}

console.log(getStageName("task 2"))
console.log(getStageName("task 7"))
console.log(getStageName("doesn't exist"))



If you call this function repeatedly, then you could create a mapper object which maps each task to it's dataTestID. You can just use mapper[task] to obtain the dataTestID. Since you are returning early, I'm assuming the tasks are unique.


const stagesTasks=[{dataTestID:"stage-0",headerText:"Backlog",initialTasks:["task 1","task 2","task 3"]},{dataTestID:"stage-1",headerText:"To Do",initialTasks:["task 4","task 5","task 6"]},{dataTestID:"stage-2",headerText:"Ongoing",initialTasks:["task 7","task 8"]},{dataTestID:"stage-3",headerText:"Done",initialTasks:["task 9"]}];

const mapper = stagesTasks.reduce((acc, o) =&gt; {
  o.initialTasks.forEach(t =&gt; acc[t] = o.dataTestID)
  return acc
}, {})

function getStageName(task) {
  return mapper[task]
}

console.log(getStageName("task 2"))
console.log(getStageName("task 7"))
console.log(getStageName("task 9"))