{company: {staff: [{..., pets: []}]}}
And what we want to do is to produce a list of all the pet cats with its owner name.
[{cat: "bla", owner: "bla"}...]
or
[{owner: "bla", cats:[...],...}, ...]
So I guess what Im trying to explain is that what is important is the change in the way of thinking about problems. When you think of them as data transformations there is a whole lot of possibilities that open. And it is not more expensive because you even have things like transducers. When you abstract away the iteration you are able to compose much more easily.
And to answer your question directly in my example the print function would print for each cat belonging to the staff which is not great flattening would be more elegant. What I wanted to convey is thinking in data transformations and abstracting away the implementation details of the iteration.
const stf = [
{name: "x", pets: [{type: "cat", name: "kitty"},
{type: "cat", name: "kitty2"}]},
{name: "y", pets: [{type: "dog"}]},
{name: "z", pets: [{type: "cat", name: "miau"}]},
];
const myTransform = ({ pets, name: ownerName }) => pets
.filter(({type}) => type === "cat")
.map(({ name: catName }) => ({ ownerName, catName }))
stf
.map(myTransform)
.flat()
.forEach(({ownerName, catName}) => console.log(`Cat ${catName} to ${ownerName}`))