I have array of objects like this:
let items: MenuPath[] = [
{ title: "Archive", path: 'archive' },
{ title: "About", path: 'about' },
{ title: "Programs", path: 'programs', children: [{ title: 'Line with...', path: 'program-line' }] },
{
title: "Blog",
path: 'blog',
children: [
{
title: "Cars",
path: 'cars',
children: [
{ title: 'Something about cars', path: 'smt-cars' },
{
title: 'Cars library',
path: 'cars-library',
children: [
{ title: 'Line of horizon', path: 'line-horizon', children: [{ title: 'Something', path: 'smt-last' }] },
{ title: 'Lineup', path: 'lineup' },
]
}
]
}
]
}
];
And i need a function that will find all objects whose title contains "line" with full hierarchy
function searchAll(items, title){
// ...
}
let result = [
[ {title: "Programs", path: "programs"}, {title: "Line with...", path: 'program-line'} ], // path: /programs/program-line
[ {title: "Blog", path: "blog"}, { title: "Cars", path: "cars" }, {title:"Cars library", path: "cars-library"}, {title: 'Line of horizon', path: 'line-horizon'} ], // path: /blog/cars/cars-library/line-horizon
[ {title: "Blog", path: "blog"}, { title: "Cars", path: "cars" }, {title:"Cars library", path: "cars-library"}, {title: 'Lineup', path: 'lineup'} ], // path: /blog/cars/cars-library/lineup
];
How can this be done?
You can use recursion here, and a stack to keep track of the hierarchy.
I've also made the search take a regex, as this works well for doing searches, eg. just putting /i
at the end allowed for a case-insenstive search.
ps: I've used structuredClone here just to make the snippet console look nicer, otherwise it create #refrences for duplicates.
const items = [
{ title: "Archive", path: 'archive' },
{ title: "About", path: 'about' },
{ title: "Programs", path: 'programs', children: [{ title: 'Line with...', path: 'program-line' }] },
{
title: "Blog",
path: 'blog',
children: [
{
title: "Cars",
path: 'cars',
children: [
{ title: 'Something about cars', path: 'smt-cars' },
{
title: 'Cars library',
path: 'cars-library',
children: [
{ title: 'Line of horizon', path: 'line-horizon', children: [{ title: 'Something', path: 'smt-last' }] },
{ title: 'Lineup', path: 'lineup' },
]
}
]
}
]
}
];
function searchAll(items, search){
const stack = [];
const results = [];
function inner(items) {
for (const i of items) {
const {title, path} = i;
stack.push({title,path})
if (search.test(i.title))
results.push(structuredClone(stack));
if (i.children) inner(i.children);
stack.pop();
}
}
inner(items);
return results;
}
console.log(searchAll(items, /line/i))
.as-console-wrapper { min-height: 100%!important; top: 0; }