I have a json array and i need to delete the subarray whose id value is 5, which is falling under the serialNo 1. I tried the following method, but its not deleting any entry in the subarray.
let Details = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
Details.map((data) => {
if (data.serialNo === "1") {
data.subArray.map((subDetails) => {
if (subDetails.id === "5") {
delete data.subArray[subDetails];
}
})
}
})
I don't know why you explicitely wants to use the map function. But the following works:
let Details = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
Details = Details.map(function (data) {
if (data.serialNo === "1") {
data.subArray = data.subArray.filter(function (sa) {
return (sa.id !== "5");
});
}
return data;
});
console.log(Details);
The first problem is that you're not returning anything from the map functions. The second problem is that data.subArray[subDetails] is undefined, subDetails is an object not an index in the data.subArray array. You can use a combination of map and filter to accomplished this instead of using delete.
let Details = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
Details.map((data) => {
if (data.serialNo === "1") {
data.subArray = data.subArray.filter((subDetails) => {
return subDetails.id !== "5";
})
}
return data;
});
console.log(Details);
If you want to stick with map what you need to do is to return undefined when subDetails.id is 5.
let Details = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
Details.map((data) => {
if (data.serialNo === "1") {
data.subArray = data.subArray.filter((subDetails) => {
return subDetails.id === "5" ? undefined : subDetails;
})
}
return data;
});
console.log(Details);
One map plus object constructor:
const arr = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
const s = 1, id = 5; // conditions
const r = arr.map(e => (e.serialNo == s)
? Object.assign(e, {'subArray': e.subArray.filter(a => a.id != id)})
: e);
console.log(JSON.stringify(r, null, 2));
Object.assign swaps old subArray with the new filtered one.
Related
I want to iterate the tree and need to get the id of all the nodes which has the children in string array. while looping it is just returning me the record but doesn't extract the name of the node.
e.g const result = ['root', 'USER', 'ROLE', 'DASHBOARD', 'BRAND', 'COMPANY'];
{
"id": "root",
"name": "Roles and Permissions",
"children": [
{
"id": "USER",
"name": "USER",
"children": [
{
"id": "1",
"name": "VIEW"
},
{
"id": "2",
"name": "CREATE"
},
{
"id": "3",
"name": "EDIT"
}
]
},
{
"id": "ROLE",
"name": "ROLE",
"children": [
{
"id": "8",
"name": "VIEW"
},
{
"id": "9",
"name": "CREATE"
},
{
"id": "10",
"name": "EDIT"
},
{
"id": "11",
"name": "DELETE"
}
]
},
{
"id": "DASHBOARD",
"name": "DASHBOARD",
"children": [
{
"id": "BRAND",
"name": "BRAND",
"children": [
{
"id": "52",
"name": "VIEW"
},
{
"id": "53",
"name": "CREATE"
},
{
"id": "54",
"name": "EDIT"
},
{
"id": "55",
"name": "DELETE"
}
]
},
{
"id": "COMPANY",
"name": "COMPANY",
"children": [
{
"id": "56",
"name": "VIEW"
},
{
"id": "57",
"name": "CREATE"
},
{
"id": "58",
"name": "EDIT"
},
{
"id": "59",
"name": "DELETE"
}
]
}
]
}
]
}
I tried various looping method to get the list, e.g. but not returning the exact name of the node.
function getParent(nodes) {
if(Array.isArray(nodes.children)) {
return nodes.children.map((node) => getParent(node));
}
return nodes.name;
}
You can store the resp in an array and return that array.
const q = {
"id": "root",
"name": "Roles and Permissions",
"children": [
{
"id": "USER",
"name": "USER",
"children": [
{
"id": "1",
"name": "VIEW"
},
{
"id": "2",
"name": "CREATE"
},
{
"id": "3",
"name": "EDIT"
}
]
},
{
"id": "ROLE",
"name": "ROLE",
"children": [
{
"id": "8",
"name": "VIEW"
},
{
"id": "9",
"name": "CREATE"
},
{
"id": "10",
"name": "EDIT"
},
{
"id": "11",
"name": "DELETE"
}
]
},
{
"id": "DASHBOARD",
"name": "DASHBOARD",
"children": [
{
"id": "BRAND",
"name": "BRAND",
"children": [
{
"id": "52",
"name": "VIEW"
},
{
"id": "53",
"name": "CREATE"
},
{
"id": "54",
"name": "EDIT"
},
{
"id": "55",
"name": "DELETE"
}
]
},
{
"id": "COMPANY",
"name": "COMPANY",
"children": [
{
"id": "56",
"name": "VIEW"
},
{
"id": "57",
"name": "CREATE"
},
{
"id": "58",
"name": "EDIT"
},
{
"id": "59",
"name": "DELETE"
}
]
}
]
}
]
}
let result = []
function r(nodes){
if(Array.isArray(nodes.children)){
result.push(nodes.name);
nodes.children.map((c) => r(c))
return result;
}
return result;
}
console.log(r(q))
You can simply use a recursive function. Here ids is an array. You can initialize it before calling the function. Call this function in your getting IDs method.
const getIdFromNodesWithChild = (node) => {
if (node.children != undefined){
ids.push(node.id)
const children_list = node.children
children_list.forEach( new_child => getIdFromNodesWithChild(new_child))
}}
caller function
const returnIds = (tree) => {
ids = []
getIdFromNodesWithChild(tree)
return (ids)
}
result : ['root', 'USER', 'ROLE', 'DASHBOARD', 'BRAND', 'COMPANY']
Can someone help me regarding my code I already search but had no luck on logic.
i am trying to get a nested drop but i get the same result on 3-child hierarchy.
this is the data from my API.
{
"data": [
{
"id": "1",
"name": "Metro Manila",
"parent": null
},
{
"id": "101",
"name": "Manila",
"parent": "1"
},
{
"id": "10101",
"name": "Malate",
"parent": "101"
},
{
"id": "10102",
"name": "Ermita",
"parent": "101"
},
{
"id": "10103",
"name": "Binondo",
"parent": "101"
},
{
"id": "102",
"name": "Makati",
"parent": "1"
},
{
"id": "10201",
"name": "Poblacion",
"parent": "102"
},
{
"id": "10202",
"name": "Bel-Air",
"parent": "102"
},
{
"id": "10203",
"name": "San Lorenzo",
"parent": "102"
},
{
"id": "10204",
"name": "Urdaneta",
"parent": "102"
},
{
"id": "103",
"name": "Marikina",
"parent": "1"
},
{
"id": "10301",
"name": "Sto Nino",
"parent": "103"
},
{
"id": "10302",
"name": "Malanday",
"parent": "103"
},
{
"id": "10303",
"name": "Concepcion I",
"parent": "103"
},
{
"id": "2",
"name": "CALABARZON",
"parent": null
},
{
"id": "201",
"name": "Laguna",
"parent": "2"
},
{
"id": "20101",
"name": "Calamba",
"parent": "201"
},
{
"id": "20102",
"name": "Sta. Rosa",
"parent": "201"
},
{
"id": "202",
"name": "Cavite",
"parent": "2"
},
{
"id": "20201",
"name": "Kawit",
"parent": "202"
},
{
"id": "203",
"name": "Batangas",
"parent": "2"
},
{
"id": "20301",
"name": "Lipa",
"parent": "203"
},
{
"id": "20302",
"name": "Tanauan",
"parent": "203"
},
{
"id": "3",
"name": "Central Luzon",
"parent": null
},
{
"id": "301",
"name": "Bulacan",
"parent": "3"
},
{
"id": "302",
"name": "Nueva Ecija",
"parent": "3"
},
{
"id": "303",
"name": "Tarlac",
"parent": "3"
},
{
"id": "304",
"name": "Pampanga",
"parent": "3"
}
]
}
this.data = result.body.data;
let parents = this.data.filter(x => x.parent == null);
let child_id = [];
let child_id2 = [];
for (let i = 0; i < parents.length; i++) {
let _myTreelist = new ParentData();
_myTreelist.data.parent = parents[i].name;
child_id = this.data.filter(x => x.parent == parents[i].id); //get child-1 with id
_myTreelist.data.child.child1 = child_id.map((item) => {
return item.name
})
for (let e = 0; e < child_id.length; e++) { //10 ids
child_id2 = this.data.filter(a => a.parent === child_id[e].id); //get child-2 with id
_myTreelist.data.child.child.child2 = child_id2.map((item) => {
return item.name
})
}
this.parentList.push(_myTreelist);
}
this is the image output I get.
it works the first and 2nd nested but in the 3rd it display same
make a recursive function
getChild(element:any,data:any[])
{
element.children=data.filter((x:any)=>x.parent==element.id)
if (element.children.length)
element.children.forEach((x:any)=>this.getChild(x,data))
else
element.children=null;
return element
}
then
treeData=this.data.filter(x=>!x.parent)
.map(x=>this.getChild(x,this.data))
stackblitz
If you use an API and an observable use pipe map
treeData$=this.service.getData().pipe(
map((data:any[])=>{
return data.filter(x=>!x.parent).map(x=>this.getChild(x,data))
})
)
I am getting below response on hitting DoctorData.api and want to sort them all with their 'ID'. Can someone show me how to sort the Output JSON data and display it same format.
Kindly Excuse my coding skills, this is my second test case. I am new to JS.
var doctorIDgeturl = geturl.geturls.getapiUrl; //'getapiUrl' is Doctor Get API
var res = await api.getRequest(doctorIDgeturl);
logger.logger().info('GET_data = ', JSON.stringify(res.data, null, 2));
var rescount = Object.keys(res.data.data.doctorList); //doctorList is the API response object for above GET API
console.log("This is Sorted Id: ");
const sortedResponse = sort(res.data, r => r.doctorListModels.associateId, ['asc']) //using ascending order to sort
console.log(sortedResponse);
Current output:
{
"message": "Record Found",
"data": {
"DoctorsList": [
{
"id": "10",
"name": "William",
"launch_date": "2018-01-24T00:00:00.000-05:00"
},
{
"id": "2",
"name": "Snow",
"launch_date": "2017-08-14T00:00:00.000-05:00"
},
{
"id": "33",
"name": "Thomas",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "3",
"name": "Ismail",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "5",
"name": "Jackson",
"launch_date": "2018-04-10T00:00:00.000-05:00"
}
Expected output after sorting:
{
"message": "Record Found",
"data": {
"DoctorsList": [
{
"id": "2",
"name": "Snow",
"launch_date": "2017-08-14T00:00:00.000-05:00"
},
{
"id": "3",
"name": "Ismail",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "5",
"name": "Jackson",
"launch_date": "2018-04-10T00:00:00.000-05:00"
},
{
"id": "10",
"name": "William",
"launch_date": "2018-01-24T00:00:00.000-05:00"
},
{
"id": "33",
"name": "Thomas",
"launch_date": "2018-11-29T00:00:00.000-05:00"
}
parseInt(r.doctorListModels.associateId) or +r.doctorListModels.associateId
it seems like it sorts the id as string not number
Sorry I can't comment because of low reputation, but here is solution.
const obj = {
"message": "Record Found",
"data": {
"DoctorsList": [{
"id": "10",
"name": "William",
"launch_date": "2018-01-24T00:00:00.000-05:00"
},
{
"id": "2",
"name": "Snow",
"launch_date": "2017-08-14T00:00:00.000-05:00"
},
{
"id": "33",
"name": "Thomas",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "3",
"name": "Ismail",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "5",
"name": "Jackson",
"launch_date": "2018-04-10T00:00:00.000-05:00"
}]
}
}
const sortedResponse = obj.data.DoctorsList.sort(function(a, b) { return parseInt(a.id) - parseInt(b.id) });
console.log(sortedResponse)
const obj = {
"message": "Record Found",
"data": {
"DoctorsList": [{
"id": "10",
"name": "William",
"launch_date": "2018-01-24T00:00:00.000-05:00"
},
{
"id": "2",
"name": "Snow",
"launch_date": "2017-08-14T00:00:00.000-05:00"
},
{
"id": "33",
"name": "Thomas",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "3",
"name": "Ismail",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "5",
"name": "Jackson",
"launch_date": "2018-04-10T00:00:00.000-05:00"
}
]
}}
obj.data.DoctorsList = obj.data.DoctorsList.sort((a, b) => parseInt(a.id) > parseInt(b.id));
console.log(obj)
I wanted to get the difference between two arrays which is nested.
let firstArray = {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "4.0",
"count": [
{
"id": "21",
"countName": "ABC",
"countThreshold": "7.0"
},
{
"id": "22",
"workscopeName": "DEF",
"countThreshold": "4242"
}
]
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "2.0"
},
{
"id": "6",
"countName": "DEF",
"countThreshold": "3.0"
}
]
}
]
}
let changedArray= {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "5",
"count": [
{
"id": "21",
"countName": "ABC",
"countThreshold": "7.0"
},
{
"id": "22",
"workscopeName": "DEF",
"countThreshold": "4242"
}
]
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "60"
},
{
"id": "6",
"countName": "DEF",
"countThreshold": "3.0"
}
]
}
]
}
Expected result:
let finalArray = {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "5",
"count": []
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "60"
}
]
}
]
}
I would like to track the diffference based on the value property inside 'levelData' array and countThreshold inside count array.
i tried repeating two arrays in for loop but was not able to repeat Any simultaneously as its nested.Do let me know any quick approach..
Thanks
Try using map to iterate for each levelData finding their respective in firstArray by name then filter by matching its properties:
let firstArray={"family":"BLUE","globalThreshold":"2.0","levelData":[{"name":"India","value":"4.0","count":[{"id":"21","countName":"ABC","countThreshold":"7.0"},{"id":"22","workscopeName":"DEF","countThreshold":"4242"}]},{"name":"FEDERAL EXPRESS CORPORATION","value":"1.0","count":[{"id":"5","countName":"ABC","countThreshold":"2.0"},{"id":"6","countName":"DEF","countThreshold":"3.0"}]}]};
let changedArray={"family":"BLUE","globalThreshold":"2.0","levelData":[{"name":"India","value":"5","count":[{"id":"21","countName":"ABC","countThreshold":"7.0"},{"id":"22","workscopeName":"DEF","countThreshold":"4242"}]},{"name":"FEDERAL EXPRESS CORPORATION","value":"1.0","count":[{"id":"5","countName":"ABC","countThreshold":"60"},{"id":"6","countName":"DEF","countThreshold":"3.0"}]}]}
var arr = changedArray.levelData.map(ele => {
var count = firstArray.levelData.find(x => x.name == ele.name).count;
ele.count = ele.count.filter(x => !count.some(y => x.id == y.id && x.countThreshold == y.countThreshold));
return ele;
})
console.log(arr);
I have following JSON structure:
{
"shops": {
"categories": {
"cat_1": {
"id": "1",
"label": "Men's Fashions",
"Brands": [{
"id": "2",
"name": "Smith"
}]
},
"cat_2": {
"id": "2",
"label": "Restaurants",
"Brands": [{
"id": "3",
"name": "KFC"
}, {
"id": "4",
"name": "SUBWAY"
}, {
"id": "5",
"name": "MLD"
}, {
"id": "6",
"name": "THAI"
}]
},
"cat_3": {
"id": "3",
"label": "Specialty Shops",
"Brands": [{
"id": "7",
"name": "BODY SHOP"
}]
}
}
}
}
I'd like to achieve something like this:
[{
"categoryid": "1",
"id": "2",
"label": "Men's Fashions",
"name": "Smith"
},
{
"categoryid": "2",
"id": "3",
"label": "Restaurants",
"name": "KFC"
},
{
"categoryid": "2",
"id": "4",
"label": "Restaurants",
"name": "SUBWAY"
},
{
"categoryid": "2",
"id": "5",
"label": "Restaurants",
"name": "MLD"
},
{
"categoryid": "2",
"id": "6",
"label": "Restaurants",
"name": "THAI"
}, {
"categoryid": "3",
"id": "7",
"label": "Specialty Shops",
"name": "BODY SHOP"
},
]
Is there an elegant way to achieve it using underscore?
I tried to use nested _.each() to do that, but feel there might be something better.
generateArray: function(obj) {
var newResult = [];
_.each(obj.categories, function(c) {
_.each(c.Brands, function(d) {
newResult.push({
"categoryid": c.id,
"id": d.id,
"label": c.label,
"name": d.name
});
});
});
return newResult;
}
Anyone can advise me which way is more efficiency at running time?
mine or #Artyom Neustroev or #Anthony Chu ?
You don't really need underscore for that task. Use simple for .. in .. and for (...) loops:
var json = {...};
var result = [];
for (var catKey in json.shops.categories) {
var currentCategory = json.shops.categories[catKey];
for (var i = 0; i < currentCategory.Brands.length; i++) {
var currentBrand = currentCategory.Brands[i];
result.push({
categoryid: currentCategory.id,
label: currentCategory.label,
id: currentBrand.id,
name: currentBrand.name
});
}
}
Fiddle here
Instead of each()'s, here's a way to do it with map()'s...
var output = _.chain(input.shops.categories)
.map(function (category) {
return _(category.Brands).map(function (brand) {
return { categoryId: category.id,
id: brand.id,
label: category.label,
name: brand.name
};
});
}).flatten().value();
JSFIDDLE