I have array of objects that include children from the array of objects and i need to find value inside parent array or find value inside childrens of this array etc. Maybe recursive. I trided like this:
var array = [
{
id: 1,
value: 'value',
children: null
},
{
id: 2,
value: 'my value',
children: [
{
id: 'child1',
value: 'my value',
children: null
},
{
id: 'child2',
value: 'value',
children: null
},
{
id: 'child3',
value: 'value,
children: [
{
id: 'childchild1',
value: 'my value',
children: null
}
]
}
]
},
{
id: 3,
value: 'value',
children: null
},
{
id: 4,
value: 'my value',
children: null
}
]
function find(searchData, target){
return target.filter((f)=>{
if(f.value.includes(searchData)){
return true
}
if(f.children){
return find(searchData, f.children)
}
})
}
find('my', array)
I have array of objects that include children from the array of objects and i need to find value inside parent array or find value inside childrens of this array etc. Maybe recursive. I trided like this:
var array = [
{
id: 1,
value: 'value',
children: null
},
{
id: 2,
value: 'my value',
children: [
{
id: 'child1',
value: 'my value',
children: null
},
{
id: 'child2',
value: 'value',
children: null
},
{
id: 'child3',
value: 'value,
children: [
{
id: 'childchild1',
value: 'my value',
children: null
}
]
}
]
},
{
id: 3,
value: 'value',
children: null
},
{
id: 4,
value: 'my value',
children: null
}
]
function find(searchData, target){
return target.filter((f)=>{
if(f.value.includes(searchData)){
return true
}
if(f.children){
return find(searchData, f.children)
}
})
}
find('my', array)
It's returns source array but i need array which includes text 'my'
Share Improve this question edited Dec 20, 2018 at 9:15 Marty asked Dec 20, 2018 at 9:13 MartyMarty 5548 silver badges30 bronze badges 2- @CertainPerformance yes, but not childrens – Marty Commented Dec 20, 2018 at 9:16
- Please include the desired output for the example you have given. – trincot Commented Dec 20, 2018 at 9:21
3 Answers
Reset to default 3Because you have a nested structure, you can't use .filter
to get all nested objects - .filter
will only return to you the matching objects on the topmost level. Instead, define an empty array on the initial call, then push
to that array when an item passes the test, and pass the array around to each recursive call. Finally, return that array:
var array=[{id:1,value:'value',children:null},{id:2,value:'my value',children:[{id:'child1',value:'my value',children:null},{id:'child2',value:'value',children:null},{id:'child3',value:'value',children:[{id:'childchild1',value:'my value',children:null}]}]},{id:3,value:'value',children:null},{id:4,value:'my value'}];
function find(searchData, target, accum=[]){
target.forEach((f)=>{
if(f.children){
find(searchData, f.children, accum)
}
if(f.value.includes(searchData)){
accum.push(f);
}
});
return accum;
}
console.log(find('my', array));
(result is probably seen more easily via browser console than via stack snippet console)
Here is a functional programming style implementation. For simplifying the output I just collected the id
values of the matches. If you want the whole object, then replace obj.id
by obj
:
const array = [{id: 1,value: 'value',children: null},{id: 2,value: 'my value',children: [{id: 'child1',value: 'my value',children: null},{id: 'child2',value: 'value',children: null},{id: 'child3',value: 'value' ,children: [{id: 'childchild1',value: 'my value',children: null}]}]},{id: 3,value: 'value',children: null},{id: 4,value: 'my value'}];
const find = (searchData, target) => (target || []).reduce(
(acc, obj) => acc.concat(obj.value.includes(searchData) ? obj.id : [],
find(searchData, obj.children)),
[]
);
const result = find('my', array);
console.log(result);
Just a bit too late, here is another recursive find:
var array = [
{
id: 1,
value: 'value',
children: null,
},
{
id: 2,
value: 'my value',
children: [
{
id: 'child1',
value: 'my value',
children: null,
},
{
id: 'child2',
value: 'value',
children: null,
},
{
id: 'child3',
value: 'value',
children: [
{
id: 'childchild1',
value: 'my value',
children: null,
},
],
},
],
},
{
id: 3,
value: 'value',
children: null,
},
{
id: 4,
value: 'my value',
},
];
function find(search, arr) {
function recur(result, search, arr) {
if (!(arr && arr.length)) {
return result;
}
return result
.concat(
...arr.filter((item) =>
item.value.includes(search),
),
)
.concat(
...arr.map((item) =>
recur([], search, item.children),
),
);
}
return recur([], search, arr);
}
console.log(find('my', array));