javascript find deeply nested objects
I need to filter objects recursively in a deeply nested array of objects using javascript, maybe with the help of lodash.
What is the cleanest way to do it, If I don't know how many nested object there will be in my array?
Let's say I have the following structure
[
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
I want to find the one with id 6
, and if it has children return true otherwise false.
Of course If I have a similar data structure but with different number of items it should work too.
javascript lodash
add a comment |
I need to filter objects recursively in a deeply nested array of objects using javascript, maybe with the help of lodash.
What is the cleanest way to do it, If I don't know how many nested object there will be in my array?
Let's say I have the following structure
[
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
I want to find the one with id 6
, and if it has children return true otherwise false.
Of course If I have a similar data structure but with different number of items it should work too.
javascript lodash
You can write a function that can iterate over the top-level items, and then modify that function to accept an input array to iterate over, and then have that function call itself recursively for each item'schildren
.
– meagar♦
Nov 19 '18 at 20:12
are any of the children refs to parents? that can cause an infinite loop when iterating. otherwise, it's a pretty straight-forward for/in, recursively calling if the typeof all[specific] =='object.
– dandavis
Nov 19 '18 at 20:15
add a comment |
I need to filter objects recursively in a deeply nested array of objects using javascript, maybe with the help of lodash.
What is the cleanest way to do it, If I don't know how many nested object there will be in my array?
Let's say I have the following structure
[
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
I want to find the one with id 6
, and if it has children return true otherwise false.
Of course If I have a similar data structure but with different number of items it should work too.
javascript lodash
I need to filter objects recursively in a deeply nested array of objects using javascript, maybe with the help of lodash.
What is the cleanest way to do it, If I don't know how many nested object there will be in my array?
Let's say I have the following structure
[
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
I want to find the one with id 6
, and if it has children return true otherwise false.
Of course If I have a similar data structure but with different number of items it should work too.
javascript lodash
javascript lodash
asked Nov 19 '18 at 20:11
ewoolewool
323
323
You can write a function that can iterate over the top-level items, and then modify that function to accept an input array to iterate over, and then have that function call itself recursively for each item'schildren
.
– meagar♦
Nov 19 '18 at 20:12
are any of the children refs to parents? that can cause an infinite loop when iterating. otherwise, it's a pretty straight-forward for/in, recursively calling if the typeof all[specific] =='object.
– dandavis
Nov 19 '18 at 20:15
add a comment |
You can write a function that can iterate over the top-level items, and then modify that function to accept an input array to iterate over, and then have that function call itself recursively for each item'schildren
.
– meagar♦
Nov 19 '18 at 20:12
are any of the children refs to parents? that can cause an infinite loop when iterating. otherwise, it's a pretty straight-forward for/in, recursively calling if the typeof all[specific] =='object.
– dandavis
Nov 19 '18 at 20:15
You can write a function that can iterate over the top-level items, and then modify that function to accept an input array to iterate over, and then have that function call itself recursively for each item's
children
.– meagar♦
Nov 19 '18 at 20:12
You can write a function that can iterate over the top-level items, and then modify that function to accept an input array to iterate over, and then have that function call itself recursively for each item's
children
.– meagar♦
Nov 19 '18 at 20:12
are any of the children refs to parents? that can cause an infinite loop when iterating. otherwise, it's a pretty straight-forward for/in, recursively calling if the typeof all[specific] =='object.
– dandavis
Nov 19 '18 at 20:15
are any of the children refs to parents? that can cause an infinite loop when iterating. otherwise, it's a pretty straight-forward for/in, recursively calling if the typeof all[specific] =='object.
– dandavis
Nov 19 '18 at 20:15
add a comment |
9 Answers
9
active
oldest
votes
Since you only want a true
of false
answer you can use some()
on the recursion, effectively doing a depth-first search, and make it pretty succinct:
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function findNested(arr, id) {
let found = arr.find(node => node.id === id)
return found
? found.children.length > 0
: arr.some((c) => findNested(c.children, id))
}
console.log(findNested(arr, 6)) // True: found with children
console.log(findNested(arr, 7)) // False: found no children
console.log(findNested(arr, 97)) // False: not found
1
I think that instead of(found && ...) ||
it would be more logical to dofound ? ... :
since if the element was found if makes no sense to still executearr.some
if the found node has no children.
– trincot
Nov 19 '18 at 20:40
1
@trincot||
has short-circuiting behavior so it doesn't execute thearr.some()
.
– Patrick Roberts
Nov 19 '18 at 20:42
2
@PatrickRoberts I think he means for the case wherefound
exists but has no children. Doesn't make sense to do DFS after that. Having said that, nice solution :)
– slider
Nov 19 '18 at 20:45
1
As slider said ^^^^ "...if the found node has no children"
– trincot
Nov 19 '18 at 20:45
1
I decided to go with your solution, and it works flawlessly without any issue, thanks!
– ewool
Nov 22 '18 at 18:22
|
show 1 more comment
Perhaps a recursive solution along the lines of this might work for you? Here, the node with supplied id is recursively searched for through the 'children' of the supplied input data. If a child node with matching id is found, a boolean result is returned based on the existence of data in that nodes children
array:
function nodeWithIdHasChildren(children, id) {
for(const child of children) {
// If this child node matches supplied id, then check to see if
// it has data in it's children array and return true/false accordinly
if(child.id === id) {
if(Array.isArray(child.children) && child.children.length > 0) {
return true
}
else {
return false
}
}
else {
const result = nodeWithIdHasChildren(child.children, id);
// If result returned from this recursion branch is not undefined
// then assume it's true or false from a node matching the supplied
// id. Pass the return result up the call stack
if(result !== undefined) {
return result
}
}
}
}
const data = [
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
console.log('node 6 has children:', nodeWithIdHasChildren( data, 6 ) )
console.log('node 7 has children:', nodeWithIdHasChildren( data, 7 ) )
console.log('node 100 has children:', nodeWithIdHasChildren( data, 7 ), '(because node 100 does not exist)' )
add a comment |
also:
function explore(myArray, searchedId) {
for (let i=0; i<myArray.length; i++) {
let el;
if (myArray[i].id == searchedId) {
el = myArray[i];
} else {
el = explore(myArray[i].children, searchedId);
}
if (el) {
return el.children.length > 0;
}
}
}
add a comment |
You can use "recursion" like below to check if id
has children or not
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function hasChildren(arr, id) {
let res = false
for (let d of arr) {
if(d.id == id) return d.children.length > 0
res = res || hasChildren(d.children, id)
if(res) return true
}
return res
}
console.log('id 4 has children? ', hasChildren(arr, 4))
console.log('id 6 has children? ', hasChildren(arr, 6))
add a comment |
You can do it using three simple javascript functions:
// Function to Flatten results
var flattenAll = function(data) {
var result = ;
var flatten = function(arr) {
_.forEach(arr, function(a) {
result.push(a);
flatten(a.children);
});
};
flatten(data);
return result;
};
// Function to search on flattened array
var search = function(flattened, id) {
var found = _.find(flattened, function(d) {
return d.id == id;
});
return found;
};
// Function to check if element is found and have children
var hasChildren = function(element) {
return element && element.children && element.children.length > 0;
}
// Usage, search for id = 6
hasChildren(search(flattenAll(your_data_object), 6))
Plunker
add a comment |
You can use a generator function to iterate the nodes recursively and simplify your logic for checking existence by using Array.prototype.some()
:
const data = [{label:'first',id:1,children:},{label:'second',id:2,children:[{label:'third',id:3,children:[{label:'fifth',id:5,children:},{label:'sixth',id:6,children:[{label:'seventh',id:7,children:}]}]},{label:'fourth',id:4,children:}]}];
function * nodes (array) {
for (const node of array) {
yield node;
yield * nodes(node.children);
}
}
const array = Array.from(nodes(data));
console.log(array.some(node => node.id === 6 && node.children.length > 0));
console.log(array.some(node => node.id === 7 && node.children.length > 0));
add a comment |
Here is another solution using recursion
and doing it via only one Array.find
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f ? f.children.length > 0 : false
}
console.log(search(data, 6)) // True: found with children
console.log(search(data, 7)) // False: found but has no children
console.log(search(data, 15)) // False: not found at all
The idea is to have a recursive function which when finds the id remembers the object.
Once we have the found (or we know we do not have an entry found) just return the children array length
or return false
.
If you want to actually return the found object
instead of the boolean for children.length
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f
}
console.log(search(data, 6)) // returns only the object with id:6
console.log(search(data, 7)) // returns only the object with id: 7
console.log(search(data, 71)) // returns undefined since nothing was found
add a comment |
The JSON.parse
reviver parameter or the JSON.stringify
replacer parameter can be used to check all values, and generate flat id lookup object with references to the nodes :
var lookup = {}, json = '[{"label":"first","id":1,"children":},{"label":"second","id":2,"children":[{"label":"third","id":3,"children":[{"label":"fifth","id":5,"children":},{"label":"sixth","id":6,"children":[{"label":"seventh","id":7,"children":}]}]},{"label":"fourth","id":4,"children":}]}]'
var result = JSON.parse(json, (key, val) => val.id ? lookup[val.id] = val : val);
console.log( 'id: 2, children count:', lookup[2].children.length )
console.log( 'id: 6, children count:', lookup[6].children.length )
console.log( lookup )
add a comment |
I suggest to use deepdash
extension for lodash
:
var id6HasChildren = _.filterDeep(arr,
function(value, key, path, depth, parent) {
if (key == 'children' && parent.id == 6 && value.length) return true;
},
{ leafsOnly: false }
).length>0;
Here is a docs for filterDeep.
And this a full test for your case.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381935%2fjavascript-find-deeply-nested-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
Since you only want a true
of false
answer you can use some()
on the recursion, effectively doing a depth-first search, and make it pretty succinct:
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function findNested(arr, id) {
let found = arr.find(node => node.id === id)
return found
? found.children.length > 0
: arr.some((c) => findNested(c.children, id))
}
console.log(findNested(arr, 6)) // True: found with children
console.log(findNested(arr, 7)) // False: found no children
console.log(findNested(arr, 97)) // False: not found
1
I think that instead of(found && ...) ||
it would be more logical to dofound ? ... :
since if the element was found if makes no sense to still executearr.some
if the found node has no children.
– trincot
Nov 19 '18 at 20:40
1
@trincot||
has short-circuiting behavior so it doesn't execute thearr.some()
.
– Patrick Roberts
Nov 19 '18 at 20:42
2
@PatrickRoberts I think he means for the case wherefound
exists but has no children. Doesn't make sense to do DFS after that. Having said that, nice solution :)
– slider
Nov 19 '18 at 20:45
1
As slider said ^^^^ "...if the found node has no children"
– trincot
Nov 19 '18 at 20:45
1
I decided to go with your solution, and it works flawlessly without any issue, thanks!
– ewool
Nov 22 '18 at 18:22
|
show 1 more comment
Since you only want a true
of false
answer you can use some()
on the recursion, effectively doing a depth-first search, and make it pretty succinct:
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function findNested(arr, id) {
let found = arr.find(node => node.id === id)
return found
? found.children.length > 0
: arr.some((c) => findNested(c.children, id))
}
console.log(findNested(arr, 6)) // True: found with children
console.log(findNested(arr, 7)) // False: found no children
console.log(findNested(arr, 97)) // False: not found
1
I think that instead of(found && ...) ||
it would be more logical to dofound ? ... :
since if the element was found if makes no sense to still executearr.some
if the found node has no children.
– trincot
Nov 19 '18 at 20:40
1
@trincot||
has short-circuiting behavior so it doesn't execute thearr.some()
.
– Patrick Roberts
Nov 19 '18 at 20:42
2
@PatrickRoberts I think he means for the case wherefound
exists but has no children. Doesn't make sense to do DFS after that. Having said that, nice solution :)
– slider
Nov 19 '18 at 20:45
1
As slider said ^^^^ "...if the found node has no children"
– trincot
Nov 19 '18 at 20:45
1
I decided to go with your solution, and it works flawlessly without any issue, thanks!
– ewool
Nov 22 '18 at 18:22
|
show 1 more comment
Since you only want a true
of false
answer you can use some()
on the recursion, effectively doing a depth-first search, and make it pretty succinct:
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function findNested(arr, id) {
let found = arr.find(node => node.id === id)
return found
? found.children.length > 0
: arr.some((c) => findNested(c.children, id))
}
console.log(findNested(arr, 6)) // True: found with children
console.log(findNested(arr, 7)) // False: found no children
console.log(findNested(arr, 97)) // False: not found
Since you only want a true
of false
answer you can use some()
on the recursion, effectively doing a depth-first search, and make it pretty succinct:
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function findNested(arr, id) {
let found = arr.find(node => node.id === id)
return found
? found.children.length > 0
: arr.some((c) => findNested(c.children, id))
}
console.log(findNested(arr, 6)) // True: found with children
console.log(findNested(arr, 7)) // False: found no children
console.log(findNested(arr, 97)) // False: not found
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function findNested(arr, id) {
let found = arr.find(node => node.id === id)
return found
? found.children.length > 0
: arr.some((c) => findNested(c.children, id))
}
console.log(findNested(arr, 6)) // True: found with children
console.log(findNested(arr, 7)) // False: found no children
console.log(findNested(arr, 97)) // False: not found
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function findNested(arr, id) {
let found = arr.find(node => node.id === id)
return found
? found.children.length > 0
: arr.some((c) => findNested(c.children, id))
}
console.log(findNested(arr, 6)) // True: found with children
console.log(findNested(arr, 7)) // False: found no children
console.log(findNested(arr, 97)) // False: not found
edited Nov 19 '18 at 20:49
answered Nov 19 '18 at 20:33
Mark MeyerMark Meyer
38.5k33159
38.5k33159
1
I think that instead of(found && ...) ||
it would be more logical to dofound ? ... :
since if the element was found if makes no sense to still executearr.some
if the found node has no children.
– trincot
Nov 19 '18 at 20:40
1
@trincot||
has short-circuiting behavior so it doesn't execute thearr.some()
.
– Patrick Roberts
Nov 19 '18 at 20:42
2
@PatrickRoberts I think he means for the case wherefound
exists but has no children. Doesn't make sense to do DFS after that. Having said that, nice solution :)
– slider
Nov 19 '18 at 20:45
1
As slider said ^^^^ "...if the found node has no children"
– trincot
Nov 19 '18 at 20:45
1
I decided to go with your solution, and it works flawlessly without any issue, thanks!
– ewool
Nov 22 '18 at 18:22
|
show 1 more comment
1
I think that instead of(found && ...) ||
it would be more logical to dofound ? ... :
since if the element was found if makes no sense to still executearr.some
if the found node has no children.
– trincot
Nov 19 '18 at 20:40
1
@trincot||
has short-circuiting behavior so it doesn't execute thearr.some()
.
– Patrick Roberts
Nov 19 '18 at 20:42
2
@PatrickRoberts I think he means for the case wherefound
exists but has no children. Doesn't make sense to do DFS after that. Having said that, nice solution :)
– slider
Nov 19 '18 at 20:45
1
As slider said ^^^^ "...if the found node has no children"
– trincot
Nov 19 '18 at 20:45
1
I decided to go with your solution, and it works flawlessly without any issue, thanks!
– ewool
Nov 22 '18 at 18:22
1
1
I think that instead of
(found && ...) ||
it would be more logical to do found ? ... :
since if the element was found if makes no sense to still execute arr.some
if the found node has no children.– trincot
Nov 19 '18 at 20:40
I think that instead of
(found && ...) ||
it would be more logical to do found ? ... :
since if the element was found if makes no sense to still execute arr.some
if the found node has no children.– trincot
Nov 19 '18 at 20:40
1
1
@trincot
||
has short-circuiting behavior so it doesn't execute the arr.some()
.– Patrick Roberts
Nov 19 '18 at 20:42
@trincot
||
has short-circuiting behavior so it doesn't execute the arr.some()
.– Patrick Roberts
Nov 19 '18 at 20:42
2
2
@PatrickRoberts I think he means for the case where
found
exists but has no children. Doesn't make sense to do DFS after that. Having said that, nice solution :)– slider
Nov 19 '18 at 20:45
@PatrickRoberts I think he means for the case where
found
exists but has no children. Doesn't make sense to do DFS after that. Having said that, nice solution :)– slider
Nov 19 '18 at 20:45
1
1
As slider said ^^^^ "...if the found node has no children"
– trincot
Nov 19 '18 at 20:45
As slider said ^^^^ "...if the found node has no children"
– trincot
Nov 19 '18 at 20:45
1
1
I decided to go with your solution, and it works flawlessly without any issue, thanks!
– ewool
Nov 22 '18 at 18:22
I decided to go with your solution, and it works flawlessly without any issue, thanks!
– ewool
Nov 22 '18 at 18:22
|
show 1 more comment
Perhaps a recursive solution along the lines of this might work for you? Here, the node with supplied id is recursively searched for through the 'children' of the supplied input data. If a child node with matching id is found, a boolean result is returned based on the existence of data in that nodes children
array:
function nodeWithIdHasChildren(children, id) {
for(const child of children) {
// If this child node matches supplied id, then check to see if
// it has data in it's children array and return true/false accordinly
if(child.id === id) {
if(Array.isArray(child.children) && child.children.length > 0) {
return true
}
else {
return false
}
}
else {
const result = nodeWithIdHasChildren(child.children, id);
// If result returned from this recursion branch is not undefined
// then assume it's true or false from a node matching the supplied
// id. Pass the return result up the call stack
if(result !== undefined) {
return result
}
}
}
}
const data = [
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
console.log('node 6 has children:', nodeWithIdHasChildren( data, 6 ) )
console.log('node 7 has children:', nodeWithIdHasChildren( data, 7 ) )
console.log('node 100 has children:', nodeWithIdHasChildren( data, 7 ), '(because node 100 does not exist)' )
add a comment |
Perhaps a recursive solution along the lines of this might work for you? Here, the node with supplied id is recursively searched for through the 'children' of the supplied input data. If a child node with matching id is found, a boolean result is returned based on the existence of data in that nodes children
array:
function nodeWithIdHasChildren(children, id) {
for(const child of children) {
// If this child node matches supplied id, then check to see if
// it has data in it's children array and return true/false accordinly
if(child.id === id) {
if(Array.isArray(child.children) && child.children.length > 0) {
return true
}
else {
return false
}
}
else {
const result = nodeWithIdHasChildren(child.children, id);
// If result returned from this recursion branch is not undefined
// then assume it's true or false from a node matching the supplied
// id. Pass the return result up the call stack
if(result !== undefined) {
return result
}
}
}
}
const data = [
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
console.log('node 6 has children:', nodeWithIdHasChildren( data, 6 ) )
console.log('node 7 has children:', nodeWithIdHasChildren( data, 7 ) )
console.log('node 100 has children:', nodeWithIdHasChildren( data, 7 ), '(because node 100 does not exist)' )
add a comment |
Perhaps a recursive solution along the lines of this might work for you? Here, the node with supplied id is recursively searched for through the 'children' of the supplied input data. If a child node with matching id is found, a boolean result is returned based on the existence of data in that nodes children
array:
function nodeWithIdHasChildren(children, id) {
for(const child of children) {
// If this child node matches supplied id, then check to see if
// it has data in it's children array and return true/false accordinly
if(child.id === id) {
if(Array.isArray(child.children) && child.children.length > 0) {
return true
}
else {
return false
}
}
else {
const result = nodeWithIdHasChildren(child.children, id);
// If result returned from this recursion branch is not undefined
// then assume it's true or false from a node matching the supplied
// id. Pass the return result up the call stack
if(result !== undefined) {
return result
}
}
}
}
const data = [
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
console.log('node 6 has children:', nodeWithIdHasChildren( data, 6 ) )
console.log('node 7 has children:', nodeWithIdHasChildren( data, 7 ) )
console.log('node 100 has children:', nodeWithIdHasChildren( data, 7 ), '(because node 100 does not exist)' )
Perhaps a recursive solution along the lines of this might work for you? Here, the node with supplied id is recursively searched for through the 'children' of the supplied input data. If a child node with matching id is found, a boolean result is returned based on the existence of data in that nodes children
array:
function nodeWithIdHasChildren(children, id) {
for(const child of children) {
// If this child node matches supplied id, then check to see if
// it has data in it's children array and return true/false accordinly
if(child.id === id) {
if(Array.isArray(child.children) && child.children.length > 0) {
return true
}
else {
return false
}
}
else {
const result = nodeWithIdHasChildren(child.children, id);
// If result returned from this recursion branch is not undefined
// then assume it's true or false from a node matching the supplied
// id. Pass the return result up the call stack
if(result !== undefined) {
return result
}
}
}
}
const data = [
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
console.log('node 6 has children:', nodeWithIdHasChildren( data, 6 ) )
console.log('node 7 has children:', nodeWithIdHasChildren( data, 7 ) )
console.log('node 100 has children:', nodeWithIdHasChildren( data, 7 ), '(because node 100 does not exist)' )
function nodeWithIdHasChildren(children, id) {
for(const child of children) {
// If this child node matches supplied id, then check to see if
// it has data in it's children array and return true/false accordinly
if(child.id === id) {
if(Array.isArray(child.children) && child.children.length > 0) {
return true
}
else {
return false
}
}
else {
const result = nodeWithIdHasChildren(child.children, id);
// If result returned from this recursion branch is not undefined
// then assume it's true or false from a node matching the supplied
// id. Pass the return result up the call stack
if(result !== undefined) {
return result
}
}
}
}
const data = [
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
console.log('node 6 has children:', nodeWithIdHasChildren( data, 6 ) )
console.log('node 7 has children:', nodeWithIdHasChildren( data, 7 ) )
console.log('node 100 has children:', nodeWithIdHasChildren( data, 7 ), '(because node 100 does not exist)' )
function nodeWithIdHasChildren(children, id) {
for(const child of children) {
// If this child node matches supplied id, then check to see if
// it has data in it's children array and return true/false accordinly
if(child.id === id) {
if(Array.isArray(child.children) && child.children.length > 0) {
return true
}
else {
return false
}
}
else {
const result = nodeWithIdHasChildren(child.children, id);
// If result returned from this recursion branch is not undefined
// then assume it's true or false from a node matching the supplied
// id. Pass the return result up the call stack
if(result !== undefined) {
return result
}
}
}
}
const data = [
{
label: "first",
id: 1,
children:
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children:
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children:
}
]
}
]
},
{
label: "fourth",
id: 4,
children:
}
]
}
];
console.log('node 6 has children:', nodeWithIdHasChildren( data, 6 ) )
console.log('node 7 has children:', nodeWithIdHasChildren( data, 7 ) )
console.log('node 100 has children:', nodeWithIdHasChildren( data, 7 ), '(because node 100 does not exist)' )
edited Nov 19 '18 at 20:42
answered Nov 19 '18 at 20:24
Dacre DennyDacre Denny
12.1k41031
12.1k41031
add a comment |
add a comment |
also:
function explore(myArray, searchedId) {
for (let i=0; i<myArray.length; i++) {
let el;
if (myArray[i].id == searchedId) {
el = myArray[i];
} else {
el = explore(myArray[i].children, searchedId);
}
if (el) {
return el.children.length > 0;
}
}
}
add a comment |
also:
function explore(myArray, searchedId) {
for (let i=0; i<myArray.length; i++) {
let el;
if (myArray[i].id == searchedId) {
el = myArray[i];
} else {
el = explore(myArray[i].children, searchedId);
}
if (el) {
return el.children.length > 0;
}
}
}
add a comment |
also:
function explore(myArray, searchedId) {
for (let i=0; i<myArray.length; i++) {
let el;
if (myArray[i].id == searchedId) {
el = myArray[i];
} else {
el = explore(myArray[i].children, searchedId);
}
if (el) {
return el.children.length > 0;
}
}
}
also:
function explore(myArray, searchedId) {
for (let i=0; i<myArray.length; i++) {
let el;
if (myArray[i].id == searchedId) {
el = myArray[i];
} else {
el = explore(myArray[i].children, searchedId);
}
if (el) {
return el.children.length > 0;
}
}
}
answered Nov 19 '18 at 20:29
AndreaAndrea
404414
404414
add a comment |
add a comment |
You can use "recursion" like below to check if id
has children or not
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function hasChildren(arr, id) {
let res = false
for (let d of arr) {
if(d.id == id) return d.children.length > 0
res = res || hasChildren(d.children, id)
if(res) return true
}
return res
}
console.log('id 4 has children? ', hasChildren(arr, 4))
console.log('id 6 has children? ', hasChildren(arr, 6))
add a comment |
You can use "recursion" like below to check if id
has children or not
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function hasChildren(arr, id) {
let res = false
for (let d of arr) {
if(d.id == id) return d.children.length > 0
res = res || hasChildren(d.children, id)
if(res) return true
}
return res
}
console.log('id 4 has children? ', hasChildren(arr, 4))
console.log('id 6 has children? ', hasChildren(arr, 6))
add a comment |
You can use "recursion" like below to check if id
has children or not
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function hasChildren(arr, id) {
let res = false
for (let d of arr) {
if(d.id == id) return d.children.length > 0
res = res || hasChildren(d.children, id)
if(res) return true
}
return res
}
console.log('id 4 has children? ', hasChildren(arr, 4))
console.log('id 6 has children? ', hasChildren(arr, 6))
You can use "recursion" like below to check if id
has children or not
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function hasChildren(arr, id) {
let res = false
for (let d of arr) {
if(d.id == id) return d.children.length > 0
res = res || hasChildren(d.children, id)
if(res) return true
}
return res
}
console.log('id 4 has children? ', hasChildren(arr, 4))
console.log('id 6 has children? ', hasChildren(arr, 6))
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function hasChildren(arr, id) {
let res = false
for (let d of arr) {
if(d.id == id) return d.children.length > 0
res = res || hasChildren(d.children, id)
if(res) return true
}
return res
}
console.log('id 4 has children? ', hasChildren(arr, 4))
console.log('id 6 has children? ', hasChildren(arr, 6))
let arr = [{label: "first",id: 1,children: },{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: },{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: }]}]},{label: "fourth",id: 4,children: }]}];
function hasChildren(arr, id) {
let res = false
for (let d of arr) {
if(d.id == id) return d.children.length > 0
res = res || hasChildren(d.children, id)
if(res) return true
}
return res
}
console.log('id 4 has children? ', hasChildren(arr, 4))
console.log('id 6 has children? ', hasChildren(arr, 6))
edited Nov 19 '18 at 20:34
answered Nov 19 '18 at 20:29
Nitish NarangNitish Narang
2,9401815
2,9401815
add a comment |
add a comment |
You can do it using three simple javascript functions:
// Function to Flatten results
var flattenAll = function(data) {
var result = ;
var flatten = function(arr) {
_.forEach(arr, function(a) {
result.push(a);
flatten(a.children);
});
};
flatten(data);
return result;
};
// Function to search on flattened array
var search = function(flattened, id) {
var found = _.find(flattened, function(d) {
return d.id == id;
});
return found;
};
// Function to check if element is found and have children
var hasChildren = function(element) {
return element && element.children && element.children.length > 0;
}
// Usage, search for id = 6
hasChildren(search(flattenAll(your_data_object), 6))
Plunker
add a comment |
You can do it using three simple javascript functions:
// Function to Flatten results
var flattenAll = function(data) {
var result = ;
var flatten = function(arr) {
_.forEach(arr, function(a) {
result.push(a);
flatten(a.children);
});
};
flatten(data);
return result;
};
// Function to search on flattened array
var search = function(flattened, id) {
var found = _.find(flattened, function(d) {
return d.id == id;
});
return found;
};
// Function to check if element is found and have children
var hasChildren = function(element) {
return element && element.children && element.children.length > 0;
}
// Usage, search for id = 6
hasChildren(search(flattenAll(your_data_object), 6))
Plunker
add a comment |
You can do it using three simple javascript functions:
// Function to Flatten results
var flattenAll = function(data) {
var result = ;
var flatten = function(arr) {
_.forEach(arr, function(a) {
result.push(a);
flatten(a.children);
});
};
flatten(data);
return result;
};
// Function to search on flattened array
var search = function(flattened, id) {
var found = _.find(flattened, function(d) {
return d.id == id;
});
return found;
};
// Function to check if element is found and have children
var hasChildren = function(element) {
return element && element.children && element.children.length > 0;
}
// Usage, search for id = 6
hasChildren(search(flattenAll(your_data_object), 6))
Plunker
You can do it using three simple javascript functions:
// Function to Flatten results
var flattenAll = function(data) {
var result = ;
var flatten = function(arr) {
_.forEach(arr, function(a) {
result.push(a);
flatten(a.children);
});
};
flatten(data);
return result;
};
// Function to search on flattened array
var search = function(flattened, id) {
var found = _.find(flattened, function(d) {
return d.id == id;
});
return found;
};
// Function to check if element is found and have children
var hasChildren = function(element) {
return element && element.children && element.children.length > 0;
}
// Usage, search for id = 6
hasChildren(search(flattenAll(your_data_object), 6))
Plunker
answered Nov 19 '18 at 21:15
Marcos BriganteMarcos Brigante
859822
859822
add a comment |
add a comment |
You can use a generator function to iterate the nodes recursively and simplify your logic for checking existence by using Array.prototype.some()
:
const data = [{label:'first',id:1,children:},{label:'second',id:2,children:[{label:'third',id:3,children:[{label:'fifth',id:5,children:},{label:'sixth',id:6,children:[{label:'seventh',id:7,children:}]}]},{label:'fourth',id:4,children:}]}];
function * nodes (array) {
for (const node of array) {
yield node;
yield * nodes(node.children);
}
}
const array = Array.from(nodes(data));
console.log(array.some(node => node.id === 6 && node.children.length > 0));
console.log(array.some(node => node.id === 7 && node.children.length > 0));
add a comment |
You can use a generator function to iterate the nodes recursively and simplify your logic for checking existence by using Array.prototype.some()
:
const data = [{label:'first',id:1,children:},{label:'second',id:2,children:[{label:'third',id:3,children:[{label:'fifth',id:5,children:},{label:'sixth',id:6,children:[{label:'seventh',id:7,children:}]}]},{label:'fourth',id:4,children:}]}];
function * nodes (array) {
for (const node of array) {
yield node;
yield * nodes(node.children);
}
}
const array = Array.from(nodes(data));
console.log(array.some(node => node.id === 6 && node.children.length > 0));
console.log(array.some(node => node.id === 7 && node.children.length > 0));
add a comment |
You can use a generator function to iterate the nodes recursively and simplify your logic for checking existence by using Array.prototype.some()
:
const data = [{label:'first',id:1,children:},{label:'second',id:2,children:[{label:'third',id:3,children:[{label:'fifth',id:5,children:},{label:'sixth',id:6,children:[{label:'seventh',id:7,children:}]}]},{label:'fourth',id:4,children:}]}];
function * nodes (array) {
for (const node of array) {
yield node;
yield * nodes(node.children);
}
}
const array = Array.from(nodes(data));
console.log(array.some(node => node.id === 6 && node.children.length > 0));
console.log(array.some(node => node.id === 7 && node.children.length > 0));
You can use a generator function to iterate the nodes recursively and simplify your logic for checking existence by using Array.prototype.some()
:
const data = [{label:'first',id:1,children:},{label:'second',id:2,children:[{label:'third',id:3,children:[{label:'fifth',id:5,children:},{label:'sixth',id:6,children:[{label:'seventh',id:7,children:}]}]},{label:'fourth',id:4,children:}]}];
function * nodes (array) {
for (const node of array) {
yield node;
yield * nodes(node.children);
}
}
const array = Array.from(nodes(data));
console.log(array.some(node => node.id === 6 && node.children.length > 0));
console.log(array.some(node => node.id === 7 && node.children.length > 0));
const data = [{label:'first',id:1,children:},{label:'second',id:2,children:[{label:'third',id:3,children:[{label:'fifth',id:5,children:},{label:'sixth',id:6,children:[{label:'seventh',id:7,children:}]}]},{label:'fourth',id:4,children:}]}];
function * nodes (array) {
for (const node of array) {
yield node;
yield * nodes(node.children);
}
}
const array = Array.from(nodes(data));
console.log(array.some(node => node.id === 6 && node.children.length > 0));
console.log(array.some(node => node.id === 7 && node.children.length > 0));
const data = [{label:'first',id:1,children:},{label:'second',id:2,children:[{label:'third',id:3,children:[{label:'fifth',id:5,children:},{label:'sixth',id:6,children:[{label:'seventh',id:7,children:}]}]},{label:'fourth',id:4,children:}]}];
function * nodes (array) {
for (const node of array) {
yield node;
yield * nodes(node.children);
}
}
const array = Array.from(nodes(data));
console.log(array.some(node => node.id === 6 && node.children.length > 0));
console.log(array.some(node => node.id === 7 && node.children.length > 0));
answered Nov 19 '18 at 23:11
Patrick RobertsPatrick Roberts
20.1k33576
20.1k33576
add a comment |
add a comment |
Here is another solution using recursion
and doing it via only one Array.find
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f ? f.children.length > 0 : false
}
console.log(search(data, 6)) // True: found with children
console.log(search(data, 7)) // False: found but has no children
console.log(search(data, 15)) // False: not found at all
The idea is to have a recursive function which when finds the id remembers the object.
Once we have the found (or we know we do not have an entry found) just return the children array length
or return false
.
If you want to actually return the found object
instead of the boolean for children.length
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f
}
console.log(search(data, 6)) // returns only the object with id:6
console.log(search(data, 7)) // returns only the object with id: 7
console.log(search(data, 71)) // returns undefined since nothing was found
add a comment |
Here is another solution using recursion
and doing it via only one Array.find
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f ? f.children.length > 0 : false
}
console.log(search(data, 6)) // True: found with children
console.log(search(data, 7)) // False: found but has no children
console.log(search(data, 15)) // False: not found at all
The idea is to have a recursive function which when finds the id remembers the object.
Once we have the found (or we know we do not have an entry found) just return the children array length
or return false
.
If you want to actually return the found object
instead of the boolean for children.length
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f
}
console.log(search(data, 6)) // returns only the object with id:6
console.log(search(data, 7)) // returns only the object with id: 7
console.log(search(data, 71)) // returns undefined since nothing was found
add a comment |
Here is another solution using recursion
and doing it via only one Array.find
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f ? f.children.length > 0 : false
}
console.log(search(data, 6)) // True: found with children
console.log(search(data, 7)) // False: found but has no children
console.log(search(data, 15)) // False: not found at all
The idea is to have a recursive function which when finds the id remembers the object.
Once we have the found (or we know we do not have an entry found) just return the children array length
or return false
.
If you want to actually return the found object
instead of the boolean for children.length
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f
}
console.log(search(data, 6)) // returns only the object with id:6
console.log(search(data, 7)) // returns only the object with id: 7
console.log(search(data, 71)) // returns undefined since nothing was found
Here is another solution using recursion
and doing it via only one Array.find
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f ? f.children.length > 0 : false
}
console.log(search(data, 6)) // True: found with children
console.log(search(data, 7)) // False: found but has no children
console.log(search(data, 15)) // False: not found at all
The idea is to have a recursive function which when finds the id remembers the object.
Once we have the found (or we know we do not have an entry found) just return the children array length
or return false
.
If you want to actually return the found object
instead of the boolean for children.length
:
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f
}
console.log(search(data, 6)) // returns only the object with id:6
console.log(search(data, 7)) // returns only the object with id: 7
console.log(search(data, 71)) // returns undefined since nothing was found
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f ? f.children.length > 0 : false
}
console.log(search(data, 6)) // True: found with children
console.log(search(data, 7)) // False: found but has no children
console.log(search(data, 15)) // False: not found at all
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f ? f.children.length > 0 : false
}
console.log(search(data, 6)) // True: found with children
console.log(search(data, 7)) // False: found but has no children
console.log(search(data, 15)) // False: not found at all
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f
}
console.log(search(data, 6)) // returns only the object with id:6
console.log(search(data, 7)) // returns only the object with id: 7
console.log(search(data, 71)) // returns undefined since nothing was found
const data = [ { label: "first", id: 1, children: }, { label: "second", id: 2, children: [ { label: "third", id: 3, children: [ { label: "fifth", id: 5, children: }, { label: "sixth", id: 6, children: [ { label: "seventh", id: 7, children: } ] } ] }, { label: "fourth", id: 4, children: } ] } ];
const search = (data, id) => {
var f, s = (d, id) => d.find(x => x.id == id ? f = x : s(x.children, id))
s(data, id)
return f
}
console.log(search(data, 6)) // returns only the object with id:6
console.log(search(data, 7)) // returns only the object with id: 7
console.log(search(data, 71)) // returns undefined since nothing was found
edited Nov 19 '18 at 23:52
answered Nov 19 '18 at 22:08
AkrionAkrion
9,43511224
9,43511224
add a comment |
add a comment |
The JSON.parse
reviver parameter or the JSON.stringify
replacer parameter can be used to check all values, and generate flat id lookup object with references to the nodes :
var lookup = {}, json = '[{"label":"first","id":1,"children":},{"label":"second","id":2,"children":[{"label":"third","id":3,"children":[{"label":"fifth","id":5,"children":},{"label":"sixth","id":6,"children":[{"label":"seventh","id":7,"children":}]}]},{"label":"fourth","id":4,"children":}]}]'
var result = JSON.parse(json, (key, val) => val.id ? lookup[val.id] = val : val);
console.log( 'id: 2, children count:', lookup[2].children.length )
console.log( 'id: 6, children count:', lookup[6].children.length )
console.log( lookup )
add a comment |
The JSON.parse
reviver parameter or the JSON.stringify
replacer parameter can be used to check all values, and generate flat id lookup object with references to the nodes :
var lookup = {}, json = '[{"label":"first","id":1,"children":},{"label":"second","id":2,"children":[{"label":"third","id":3,"children":[{"label":"fifth","id":5,"children":},{"label":"sixth","id":6,"children":[{"label":"seventh","id":7,"children":}]}]},{"label":"fourth","id":4,"children":}]}]'
var result = JSON.parse(json, (key, val) => val.id ? lookup[val.id] = val : val);
console.log( 'id: 2, children count:', lookup[2].children.length )
console.log( 'id: 6, children count:', lookup[6].children.length )
console.log( lookup )
add a comment |
The JSON.parse
reviver parameter or the JSON.stringify
replacer parameter can be used to check all values, and generate flat id lookup object with references to the nodes :
var lookup = {}, json = '[{"label":"first","id":1,"children":},{"label":"second","id":2,"children":[{"label":"third","id":3,"children":[{"label":"fifth","id":5,"children":},{"label":"sixth","id":6,"children":[{"label":"seventh","id":7,"children":}]}]},{"label":"fourth","id":4,"children":}]}]'
var result = JSON.parse(json, (key, val) => val.id ? lookup[val.id] = val : val);
console.log( 'id: 2, children count:', lookup[2].children.length )
console.log( 'id: 6, children count:', lookup[6].children.length )
console.log( lookup )
The JSON.parse
reviver parameter or the JSON.stringify
replacer parameter can be used to check all values, and generate flat id lookup object with references to the nodes :
var lookup = {}, json = '[{"label":"first","id":1,"children":},{"label":"second","id":2,"children":[{"label":"third","id":3,"children":[{"label":"fifth","id":5,"children":},{"label":"sixth","id":6,"children":[{"label":"seventh","id":7,"children":}]}]},{"label":"fourth","id":4,"children":}]}]'
var result = JSON.parse(json, (key, val) => val.id ? lookup[val.id] = val : val);
console.log( 'id: 2, children count:', lookup[2].children.length )
console.log( 'id: 6, children count:', lookup[6].children.length )
console.log( lookup )
var lookup = {}, json = '[{"label":"first","id":1,"children":},{"label":"second","id":2,"children":[{"label":"third","id":3,"children":[{"label":"fifth","id":5,"children":},{"label":"sixth","id":6,"children":[{"label":"seventh","id":7,"children":}]}]},{"label":"fourth","id":4,"children":}]}]'
var result = JSON.parse(json, (key, val) => val.id ? lookup[val.id] = val : val);
console.log( 'id: 2, children count:', lookup[2].children.length )
console.log( 'id: 6, children count:', lookup[6].children.length )
console.log( lookup )
var lookup = {}, json = '[{"label":"first","id":1,"children":},{"label":"second","id":2,"children":[{"label":"third","id":3,"children":[{"label":"fifth","id":5,"children":},{"label":"sixth","id":6,"children":[{"label":"seventh","id":7,"children":}]}]},{"label":"fourth","id":4,"children":}]}]'
var result = JSON.parse(json, (key, val) => val.id ? lookup[val.id] = val : val);
console.log( 'id: 2, children count:', lookup[2].children.length )
console.log( 'id: 6, children count:', lookup[6].children.length )
console.log( lookup )
edited Nov 20 '18 at 9:09
answered Nov 20 '18 at 8:59
SlaiSlai
15.3k32335
15.3k32335
add a comment |
add a comment |
I suggest to use deepdash
extension for lodash
:
var id6HasChildren = _.filterDeep(arr,
function(value, key, path, depth, parent) {
if (key == 'children' && parent.id == 6 && value.length) return true;
},
{ leafsOnly: false }
).length>0;
Here is a docs for filterDeep.
And this a full test for your case.
add a comment |
I suggest to use deepdash
extension for lodash
:
var id6HasChildren = _.filterDeep(arr,
function(value, key, path, depth, parent) {
if (key == 'children' && parent.id == 6 && value.length) return true;
},
{ leafsOnly: false }
).length>0;
Here is a docs for filterDeep.
And this a full test for your case.
add a comment |
I suggest to use deepdash
extension for lodash
:
var id6HasChildren = _.filterDeep(arr,
function(value, key, path, depth, parent) {
if (key == 'children' && parent.id == 6 && value.length) return true;
},
{ leafsOnly: false }
).length>0;
Here is a docs for filterDeep.
And this a full test for your case.
I suggest to use deepdash
extension for lodash
:
var id6HasChildren = _.filterDeep(arr,
function(value, key, path, depth, parent) {
if (key == 'children' && parent.id == 6 && value.length) return true;
},
{ leafsOnly: false }
).length>0;
Here is a docs for filterDeep.
And this a full test for your case.
answered Jan 15 at 18:50
Yuri GorYuri Gor
653413
653413
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381935%2fjavascript-find-deeply-nested-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You can write a function that can iterate over the top-level items, and then modify that function to accept an input array to iterate over, and then have that function call itself recursively for each item's
children
.– meagar♦
Nov 19 '18 at 20:12
are any of the children refs to parents? that can cause an infinite loop when iterating. otherwise, it's a pretty straight-forward for/in, recursively calling if the typeof all[specific] =='object.
– dandavis
Nov 19 '18 at 20:15