I have nested children in my document i want find document any children._id
my document look like below.
For Example:
I want this children._id "PxX4EYMYVDOphx8XU" how to find this document.
[{
"_id": "v4jdHchuogyumed7f",
"name": "products",
"children": [{
"_id": "fDE1kyR081Y44aO7h",
"name": "Clothes",
"children": [{
"_id": "l464EYMYVDOphx8XU",
"name": "Shoes",
"children": [{
"_id": "PxX4EYMYVDOphx8XU",
"name": "Black Shoes"
}]
}, {
"_id": "gUHcdTuPxXhauIWaZ",
"name": "Shirts"
}]
}, {
"_id": "svcdrpPybHJf0KiBi",
"name": "Flowers",
"children": [{
"_id": "gdEk85byoRCWxStTf",
"name": "Red Flowers"
}]
}]
}]
You need to recursively walk the object and match _id then return the parent object. An example could be.
var walk = returnExports;
var x = [{
"_id": "v4jdHchuogyumed7f",
"name": "products",
"children": [{
"_id": "fDE1kyR081Y44aO7h",
"name": "Clothes",
"children": [{
"_id": "l464EYMYVDOphx8XU",
"name": "Shoes",
"children": [{
"_id": "PxX4EYMYVDOphx8XU",
"name": "Black Shoes"
}]
}, {
"_id": "gUHcdTuPxXhauIWaZ",
"name": "Shirts"
}]
}, {
"_id": "svcdrpPybHJf0KiBi",
"name": "Flowers",
"children": [{
"_id": "gdEk85byoRCWxStTf",
"name": "Red Flowers"
}]
}]
}];
var find = 'PxX4EYMYVDOphx8XU';
var children;
var parent;
walk(x, Object.keys, function(value, prop, object, depth) {
if (prop === 'children' && Array.isArray(value)) {
children = value;
walk.STOP;
}
if (prop === '_id' && value === find) {
parent = children.find(function(obj) {
return object._id === find;
});
return walk.BREAK;
}
});
console.log(parent);
<script src="https://rawgithub.com/Xotic750/object-walk-x/master/lib/object-walk-x.js"></script>
https://www.npmjs.com/package/object-walk-x if you don't want to write your own object walker.
Related
Hello stackoverflow community! I've been creating my own fullstack application for a while now, on the NEXTjs framework. This is going pretty well!! Unfortunately, I got stuck on a JSON import object for a treeview component. The treeview component must be populated using a specific nested structure, along with which treeview item should be selected on an initial render.
I managed to get the correct JSON object from the database, using a sql recursive tree function.
const jsonObject =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
"children": []
},
{
"id": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"label": "sub category 1.2.2",
"children": []
}
]
}
]
}
The problem is that this object, with categories needs to be updated with a 'checked: "true"' or 'checked: "false"' key value pair based on the existence in the referenceSelectedCategories array. And I don't know how to do this; maintaining the structure and object as needed.
const desiredOutputJsonObject =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
** "checked": "false",**
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
** "checked": "true",**
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
** "checked": "false",**
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
** "checked": "false",**
"children": []
},
{
"id": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"label": "sub category 1.2.2",
** "checked": "true",**
"children": []
}
]
}
]
}
const referenceSelectedCategories =
[
{
"categoryId": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2"
},
{
"categoryId": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "b2e8681b-eec4-404d-8f87-c6314db42e30"
}
]
I've read several stackoverflow questions, also searched for examples, but can't get it to work. Could someone help me out here?
Some extra information:
Code language I'm using is REACT on NEXTjs framework;
Treeview component could have a dept of max 5 levels;
The structure of the JSON object doesn't change, it's exactly as presented above.
The "id" in the JSON object corresponds to the "categoryId" in the array.
Do you need more information? :) Just ask, I'll provide you with the extra details!
Kind Regards,
Chris
A straight forward solution with recursive method. Done a quick test, working fine. If any issues found, please point it out.
const parentObj =
[
{
"categoryId": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2"
},
{
"categoryId": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "b2e8681b-eec4-404d-8f87-c6314db42e30"
}
]
const existingId = parentObj.map((item)=> (item.Id))
const childobj =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
"children": []
},
{
"id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2",
"label": "sub category 1.2.2",
"children": []
}
]
}
]
}
const childObj = [childobj]
const updateData=(obj)=> {
if(existingId.includes(obj.id)) obj['checked'] = true; else obj['checked'] = false
}
const traverse=(childObj)=> {
for(const obj of childObj) {
updateData(obj);
if(obj.children.length > 0) traverse(obj.children);
}
}
traverse(childObj);
Here you can ty this logic :
let desiredOutputJsonObject = {
id: "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
label: "main category 1",
checked: false,
children: [
{
id: "12e544bc-91b1-4e5d-bdbc-2163a5618305",
label: "sub category 1.1",
checked: true,
children: [],
},
{
id: "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
label: "sub category 1.2",
checked: false,
children: [
{
id: "903a727f-d94d-44ff-b2f6-a985fd167343",
label: "sub category 1.2.1",
checked: false,
children: [],
},
{
id: "fb344480-8588-4ce3-9662-f8e89069e4b4",
label: "sub category 1.2.2",
checked: true,
children: [
{
id: "fb344480-8588-4ce3-9662-f8e89069e4b9",
label: "sub category 1.2.2",
checked: false,
children: [],
},
],
},
],
},
],
};
let referenceSelectedCategories = [
{
categoryId: "12e544bc-91b1-4e5d-bdbc-2163a5618305",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "f82b0f63-3f39-486c-9157-5c7683b8e3b2",
},
{
categoryId: "fb344480-8588-4ce3-9662-f8e89069e4b4",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "b2e8681b-eec4-404d-8f87-c6314db42e30",
},
{
categoryId:"fb344480-8588-4ce3-9662-f8e89069e4b9",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "b2e8681b-eec4-404d-8f87-c6314db42e30",
},
];
let stack = [desiredOutputJsonObject];
while (stack.length) {
let desiredOutput = stack.pop();
if (desiredOutput.children) {
desiredOutput.children.forEach((node) => {
//get node whose id == category id
let result = referenceSelectedCategories.find(
(obj) => obj.categoryId === node.id
);
// while traversing if we get referenceSelectedCategories.categoryId ==desiredOutputJsonObject.id
if (result) {
node.checked = true;
}
// for traverse purpose
if (node.children.length) {
stack.push(node);
}
});
}
}
console.log(desiredOutputJsonObject);
Right now I have an array of object with children that also have an array of objects.
[
{
"code": "mock-code",
"name": "mock-name",
"children": [
{
"code": "mock-child-code",
"name": "mock-child-name",
},
{
"code": "mock-child-code",
"name": "mock-child-name",
},
],
},
{
"code": "mock-code",
"name": "mock-name",
"children": [],
},
{
"code": "mock-code",
"name": "mock-name",
"children": [
{
"code": "mock-code",
"name": "mock-name",
}
],
}
]
I want to extract the children array and concat them to the parent array like below.
[
{
"code": "m1",
"name": "mock-name",
"children": [
{
"code": "mc-1",
"name": "mn-1",
},
{
"code": "mc-2",
"name": "mn-2",
},
],
},
{
"code": "m2",
"name": "mock-name",
"children": [],
},
{
"code": "mm3",
"name": "mock-name",
"children": [
{
"code": "mc-3",
"name": "mn-3",
}
],
}
{
"code": "mc-1",
"name": "mn-1",
},
{
"code": "mc-2",
"name": "mn-2",
},
{
"code": "mc-3",
"name": "mn-3",
}
]
What are someways to do this. I'm currently looping though the child array creating a new array checking if it's not empty. It all seems a bit messy. Is there a clean way to do this?
let fullList = New Array()
parentData.forEach(element => {
if (!!element.children.length) {
fullList.push(element.children);
}
});
return parentData.concat(fullList);
This isn't giving me the desired results since it's adding another array to the parent object but this is where I am at.
const newArray = originalArray.flatMap(element => [element, ...element.children])
This should do it, and as a bonus will preserve the order (parent1, parent1's children, parent2, parent2's children etc.)
Of course, this works if you have only one level of nesting. If you have greater depth level, that would be a bit more complex, probably using Array.prototype.reduce().
This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 5 years ago.
I have the following json:
{
"menu": [{
"name": "vegetation",
"id": "1",
"children": [
{
"name": "landuse",
"id": "1.1",
"children": [
{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
}
]
}]
}
I want to dynamically access the objects whose value of "children" is null and store the "name" of these objects in a variable. For example in this case either forest area or plantation. How can I do this using javascript or jquery?
You don't need jQuery for this, a simple for will do and, most likely, it's faster than anything else:
var childless = [],
checkForChildren = function(items){
for (var i = 0; i < items.length; i++) {
if (items[i].children)
checkForChildren(items[i].children);
else
childless.push(items[i]);
}
};
// test it:
var menu = [{
"name": "vegetation",
"id": "1",
"children": [{
"name": "landuse",
"id": "1.1",
"children": [{
"name": "forest area",
"id": "1.1.1",
"children": null
},{
"name": "plantation",
"id": "1.1.2",
"children": null
}]
}]
}];
checkForChildren(menu);
console.log(childless);
Recursion comes to mind.
var childless = [];
var recursive_function = function(obj){
if(obj.children == null){
childless.push(obj);
} else {
$.each(obj.children, function(child){
recursive_function(child);
}
}
};
$.each(json_obj.menu, function(root_level){
recursive_function(root_level);
});
console.log(childless);
console.log($.map(childless, function(x){return x.name;}));
var test = {
"menu": [{
"name": "vegetation",
"id": "1",
"children": [{
"name": "landuse",
"id": "1.1",
"children": [{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
}]
}]
};
var hasNullChildren = [];
function checkChildren ( children ) {
//loop over all children
children.forEach(function(child){
//if no children, add name to list
if (!child.children) hasNullChildren.push(child.name);
//check nested children
else checkChildren(child.children);
});
}
//start the recursion loop
checkChildren(test.menu);
console.log(hasNullChildren);
Recursively iterating through the array and searching for the children = null, gives the array with all the names of objects.
const obj = {
"menu": [{
"name": "vegetation",
"id": "1",
"children": [
{
"name": "landuse",
"id": "1.1",
"children": [
{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
},{
"name": "landuse",
"id": "1.1",
"children": null
}
]
}]
}
function getNameWithNullChildren(arr) {
let array = [];
arr.forEach(item => {
if(item.children === null) {
array.push(item.name);
} else {
array = getNameWithNullChildren(item.children);
}
});
return array;
}
console.log(getNameWithNullChildren(obj.menu));
I want to append json data to bring tree view structure. Initially I had created static tree view this is my fiddle code with json tree view: https://jsfiddle.net/ak3zLzgd/6/
Here I have challenges to append three level level json data instead of static html code.
Exactly inside retailer digital marketing > sub-ToI > semi-sub-TOI > super-sub-TOI all the thirditems json array is appending ti first value only . For more info check this fiddle: https://jsfiddle.net/ak3zLzgd/6/
var json = {
"category": [{
"title": "Customer Satisfaction",
"id": "nnanet:category/certified-pre-owned",
"items": [{
"title": "Bulletins",
"id": "nnanet:category/customer-satisfaction/bulletins",
"thirditems": [{
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}, {
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}]
}, {
"title": "Consumer Affairs",
"id": "nnanet:category/customer-satisfaction/consumer-affairs"
}, {
"title": "Loyalty",
"id": "nnanet:category/customer-satisfaction/loyalty",
"thirditems": [{
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}, {
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}]
}]
}, {
"title": "Retailer Digital Marketing",
"id": "nnanet:category/retailer-digital-marketing",
"items": [{
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi",
"thirditems": [{
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}, {
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}]
}, {
"title": "Basics",
"id": "nnanet:category/retailer-digital-marketing/reference-guide/basics"
}, {
"title": "International",
"id": "nnanet:category/retailer-digital-marketing/international"
}]
}, {
"title": "Finance Today",
"id": "nnanet:category/customer-satisfaction/bulletins/finance-today",
"items": [{
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi",
"thirditems": [{
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}, {
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}]
}, {
"title": "Basics",
"id": "nnanet:category/retailer-digital-marketing/reference-guide/basics"
}, {
"title": "International",
"id": "nnanet:category/retailer-digital-marketing/international"
}]
}, {
"title": "Annual",
"id": "nnanet:category/customer-satisfaction/bulletins/finance-today/revenue/annual",
"items": [{
"title": "TOI",
"id": "nnanet:category/retailer-digital-marketing/toi"
}, {
"title": "Basics",
"id": "nnanet:category/retailer-digital-marketing/reference-guide/basics"
}, {
"title": "International",
"id": "nnanet:category/retailer-digital-marketing/international"
}]
}]
};
function expander(){
var tree = document.querySelectorAll('ul.tree a:not(:last-child)');
for(var i = 0; i < tree.length; i++){
tree[i].addEventListener('click', function(e) {
var element = e.target.parentElement; //actually this is just the elem itself
var parent = element.parentElement
var opensubs = parent.querySelectorAll(':scope .open');
console.log(opensubs);
var classList = element.classList;
if(opensubs.length !=0) {
for(var i = 0; i < opensubs.length; i++){
opensubs[i].classList.remove('open');
}
}
classList.add('open');
});
}
}
$(function(){
var tree = $("ul.tree");
$.each(json.category,function(category){
var categoryValue = json.category[category];
tree.append('<li>'+categoryValue.title+'<ul></ul></li>');
var el = tree.children("li").children("ul");
$.each(categoryValue.items,function(itemId){
var item = categoryValue.items[itemId];
$(el[category]).append('<li>'+item.title+'</li>');
if(item.thirditems){
$(el[category]).children("li").append('<ul></ul>');
var el1 = el.children("li").children("ul");
$.each(item.thirditems,function(thirdItemId){
var thirdItem = item.thirditems[thirdItemId];
console.log(el1[itemId]);
$(el1[itemId]).append('<li>'+thirdItem.title+'<ul></ul></li>');
});
}
});
});
expander();
});
Output : check this fiddle : https://jsfiddle.net/ak3zLzgd/6/
Hi I have a json array in the below format.
{
"data": {
"title": "MainNode"
},
"children": [{
"data": {
"title": "Firstchild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "Firstchildschild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "FirstchildschildsChild",
"description": "Texttexttext"
}
}]
}, {
"data": {
"title": "FirstchildsSecondchild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "FirstchildsSecondchildsChild",
"description": "Texttexttext"
}
}]
}]
}]
}
I have to read the array based on the title text value and list that particular data and its sub data.
For eg. If my input (title value will get from the http URL as follows) is "Firstchild/Firstchildschild/" then I have to list FirstchildschildsChild and its description.
If my input is input is /Firstchild/ then I have to list Firstchildschild & FirstchildsSecondchild data and its sub childs name.
Using jquery how can I fetch records as I mentioned above. Please advise the best way to process this json instead of using lot of loops?
Ok just for these necessities (and believe this is really a big necessity) i had invented an Object method called Object.prototype.getNestedValue() which dynamically fetches you the nested value from deeply nested Objects. All you need to provide is a string for the properties and a number for the array indices in the proper order. OK lets see...
Object.prototype.getNestedValue = function(...a) {
return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};
var JSONobj = {
"data": {
"title": "MainNode"
},
"children": [{
"data": {
"title": "Firstchild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "Firstchildschild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "FirstchildschildsChild",
"description": "Texttexttext"
}
}]
}, {
"data": {
"title": "FirstchildsSecondchild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "FirstchildsSecondchildsChild",
"description": "Texttexttext"
}
}]
}]
}]
},
value = JSONobj.getNestedValue("children",0,"children",0,"data","title");
console.log(value); // Firstchildschild
var a = "children",
b = 0,
c = "data",
d = "title";
value2 = JSONobj.getNestedValue(...[a,b,a,b,c,d])
console.log(value2); // Firstchildschild
It also has a sister called Object.prototype.setNestedValue().
var obj = jQuery.parseJSON( '
"data": {
"title": "MainNode"
},
"children": [{
"data": {
"title": "Firstchild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "Firstchildschild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "FirstchildschildsChild",
"description": "Texttexttext"
}
}]
}, {
"data": {
"title": "FirstchildsSecondchild",
"description": "Texttexttext"
},
"children": [{
"data": {
"title": "FirstchildsSecondchildsChild",
"description": "Texttexttext"
}
}]
}]
}]
}' );
alert( obj.name === "data" );
You have to parse the element
obj.name === "data"
in the next link