I have below data from my API call and I am working with reduce function to set data as per my requirement. But not able to produce it, please check below code and required output. Also check the function I am trying and suggest me way to create the response.
API Response:
let cmpRecords = {
"status": "success",
"message": "Record Fetched Successfully",
"data": [
{
"_id": "6098ff60a8e9ee2c7c116d6e",
"record": {
"creatorName": "ABC",
"modifierName": ""
},
"is_deleted": "0"
},
{
"_id": "6098ff60a8e9ee2c7c116d6e",
"record": {
"creatorName": "ABC",
"modifierName": ""
},
"is_deleted": "0"
},
{
"_id": "6098ff60a8e9ee2c7c116d6z",
"record": {
"creatorName": "XYZ",
"modifierName": ""
},
"is_deleted": "0"
},
...
]
}
Required Output ::
{
"status": "success",
"message": "Record Fetched Successfully",
"data": [
{
"name": "ABC",
"record": [
{
"_id": "6098ff60a8e9ee2c7c116d6e",
"record": {
"creatorName": "ABC",
"modifierName": ""
},
"is_deleted": "0"
},
{
"_id": "6098ff60a8e9ee2c7c116d6e",
"record": {
"creatorName": "ABC",
"modifierName": ""
},
"is_deleted": "0"
}
]
},
{
"name": "XYZ",
"record": [
{
"_id": "6098ff60a8e9ee2c7c116d6z",
"record": {
"creatorName": "XYZ",
"modifierName": ""
},
"is_deleted": "0"
}
]
}
]
}
As I want to seperate record of same user, with key and value & key and object I used reduce function for this
group = cmpRecords.reduce((r, a) => {
let name = a.record.creatorName;
let record = a;
r[name] = [...r[name] || [], record];
return r;
}, {});
This responds with
"data": [
"ABC":[
{
"_id": "6098ff60a8e9ee2c7c116d6e",
"record": {
"creatorName": "ABC",
"modifierName": ""
},
"is_deleted": "0"
},
...
]
]
I tried other ways but not getting required response.
You can use Array.reduce() to group your records by name, the output here should be what you require:
const cmpRecords = { "status": "success", "message": "Record Fetched Successfully", "data": [ { "_id": "6098ff60a8e9ee2c7c116d6e", "record": { "creatorName": "ABC", "modifierName": "" }, "is_deleted": "0" }, { "_id": "6098ff60a8e9ee2c7c116d6e", "record": { "creatorName": "ABC", "modifierName": "" }, "is_deleted": "0" }, { "_id": "6098ff60a8e9ee2c7c116d6z", "record": { "creatorName": "XYZ", "modifierName": "" }, "is_deleted": "0" }, ] }
const output = {
...cmpRecords,
data: Object.values(cmpRecords.data.reduce((acc, cur) => {
acc[cur.record.creatorName] = acc[cur.record.creatorName] || { name: cur.record.creatorName, record: [] };
acc[cur.record.creatorName].record.push(cur);
return acc;
}, {}))
}
console.log('Output:', output)
Related
I have a JSON like this, how to get the value of StatusDescription? I tried many times but the result is undefined. Here is my JSON:
{
"meta": {
"a2": 200,
"ta": "dasd",
"asdd": "asdda"
},
"data": {
"items": [
{
"id": "",
"number": "",
"origin_info": {
"ItemReceived": "2021-10-02 02:07:49",
"phone": 123456789,
"trackinfo": [
{
"StatusDescription": "what i need",
"Details": "",
"substatus": "ok"
},
{
"StatusDescription": "what i need",
"Details": "",
"substatus": "ok"
}
]
},
"destination_info": null,
"lastEvent": "grgrgrgrgr",
"lastUpdateTime": "mewmemew"
}
]
}
}
I'm using in my NodeJS app, like myapp.js, and console.log()
Try this
I stored your sample json in variable json
var json = {
"meta": {
"a2": 200,
"ta": "dasd",
"asdd": "asdda"
},
"data": {
"items": [
{
"id": "",
"number": "",
"origin_info": {
"ItemReceived": "2021-10-02 02:07:49",
"phone": 123456789,
"trackinfo": [
{
"StatusDescription": "what i need",
"Details": "",
"substatus": "ok"
},
{
"StatusDescription": "what i need",
"Details": "",
"substatus": "ok"
}
]
},
"destination_info": null,
"lastEvent": "grgrgrgrgr",
"lastUpdateTime": "mewmemew"
}
]
}
}
Accessed it like below
console.log(json.data.items[0].origin_info.trackinfo[0].StatusDescription);
Items is an array and we took array element 0.
trackinfo again is an array and we took array element 0.
We can change array index or loop through and get required values.
You have to iterate through your items and trackinfo to get to StatusDescription. Try this one.
const data = {
"meta": {
"a2": 200,
"ta": "dasd",
"asdd": "asdda"
},
"data": {
"items": [
{
"id": "",
"number": "",
"origin_info": {
"ItemReceived": "2021-10-02 02:07:49",
"phone": 123456789,
"trackinfo": [
{
"StatusDescription": "what i need",
"Details": "",
"substatus": "ok"
},
{
"StatusDescription": "what i need",
"Details": "",
"substatus": "ok"
}
]
},
"destination_info": null,
"lastEvent": "grgrgrgrgr",
"lastUpdateTime": "mewmemew"
}
]
}
}
const items = data.data.items.map(item => item)
const trackinfo = items.map(item => item.origin_info.trackinfo).flat()
console.log(trackinfo)
const statusDescription = trackinfo.map(trackinfo => trackinfo.StatusDescription)
console.log(statusDescription)
I have a top level JSON structure as follows:
{
"video": [],
"messages": [],
"notifications": []
}
and i have a database output (in variable "result") as follows i want to push into the "video" array:
[
{
"_id": "5f98ab906439155cfc6f9afb",
"status": "NOT_STARTED",
"date": "2020-10-27T23:21:52.683Z",
"callInvitees": [
{
"username": "user1"
},
{
"username": "user2"
}
]
},
{
"_id": "5f98aba0789e163e0c78908f",
"status": "NOT_STARTED",
"date": "2020-10-27T23:22:08.048Z",
"callInvitees": [
{
"username": "user1"
}
]
}
]
My code is:
let dashboardJSON = { "video": [], "messages": [], "notifications": [] };
dashboardJSON.video.push(result)
It works but i am ending up with too many arrays (i think) - it looks as follows:
{
"video": [
[
{
"_id": "5f98ab906439155cfc6f9afb",
"status": "NOT_STARTED",
"date": "2020-10-27T23:21:52.683Z",
"callInvitees": [
{
"username": "user1"
},
{
"username": "user2"
}
]
},
{
"_id": "5f98aba0789e163e0c78908f",
"status": "NOT_STARTED",
"date": "2020-10-27T23:22:08.048Z",
"callInvitees": [
{
"username": "user1"
}
]
}
]
],
"messages": [],
"notifications": []
}
I want "video": [ { ... }, { ... } ] whereas i have "video": [[ { ... }, { ... } ]]
How can i resolve this?
You can use the spread operator as follows:
let result = [
{
"_id": "5f98ab906439155cfc6f9afb",
"status": "NOT_STARTED",
"date": "2020-10-27T23:21:52.683Z",
"callInvitees": [
{
"username": "user1"
},
{
"username": "user2"
}
]
},
{
"_id": "5f98aba0789e163e0c78908f",
"status": "NOT_STARTED",
"date": "2020-10-27T23:22:08.048Z",
"callInvitees": [
{
"username": "user1"
}
]
}
]
let dashboardJSON = { "video": [], "messages": [], "notifications": [] };
dashboardJSON.video.push(...result)
console.log(dashboardJSON);
Just use Array.prototype.map() method. Map method returns a new array with the result by using the provided function.
const ret = {
video: [],
messages: [],
notifications: [],
};
const data = [
{
_id: '5f98ab906439155cfc6f9afb',
status: 'NOT_STARTED',
date: '2020-10-27T23:21:52.683Z',
callInvitees: [
{
username: 'user1',
},
{
username: 'user2',
},
],
},
{
_id: '5f98aba0789e163e0c78908f',
status: 'NOT_STARTED',
date: '2020-10-27T23:22:08.048Z',
callInvitees: [
{
username: 'user1',
},
],
},
];
ret.video = data.map((x) => x);
console.log(ret);
Check for the decimal id and group them accordingly.
Below are the sample and recommended JSON's
Sample JSON
{
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
Would like to iterate and Re-structure the above JSON into below recommended format.
Logic: Should check the id(with and without decimals) and group them based on the number.
For Example:
1, 1.1, 1.2.3, 1.4.5 => data1: [{id: 1},{id: 1.1}....]
2, 2.3, 2.3.4 => data2: [{id: 2},{id: 2.3}....]
3, 3.1 => data3: [{id: 3},{id: 3.1}]
Recommended JSON
{
"results": [
{
"data1": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
}
]
},
{
"data2": [
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
}
]
},
{
"data3": [
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
}
]
},
{
"data4": [
{
"name": "Download",
"id": "4.2"
}
]
}
]
}
I have tried the below solution but it doesn't group the object
var formatedJSON = [];
results.map(function(d,i) {
formatedJSON.push({
[data+i]: d
})
});
Thanks in advance.
You can use reduce like this. The idea is to create a key-value pair for each data1, data2 etc so that values in this object are the values you need in the final array. Then use Object.values to get those as an array.
const sampleJson = {"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]}
const grouped = sampleJson.results.reduce((a, v) => {
const key = `data${parseInt(v.id)}`;
(a[key] = a[key] || {[key]: []})[key].push(v);
return a;
},{});
console.log({results: Object.values(grouped)})
One liner / Code-golf:
let s={"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]},k;
console.log({results:Object.values(s.results.reduce((a,v)=>(k=`data${parseInt(v.id)}`,(a[k] = a[k]||{[k]:[]})[k].push(v),a),{}))})
Here you go:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
let newSet = new Set();
data.results.forEach(e => {
let key = e.id.substring(0, e.id.indexOf('.'));
console.log(key);
if (newSet.has(key) == false) {
newSet.add(key);
newSet[key] = [];
}
newSet[key].push(e.id);
});
console.log(newSet);
Here's how you'd do it:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
var newData = {
"results": {}
};
data.results.forEach(item => {
var num = item.id.slice(0, 1);
if (newData.results["data" + num]) {
newData.results["data" + num].push(item);
} else {
newData.results["data" + num] = [item];
}
})
data = newData;
console.log(data);
What this does is it iterates through each item in results, gets the number at the front of this item's id, and checks if an array of the name data-{num} exists. If the array exists, it's pushed. If it doesn't exist, it's created with the item.
let input = getInput();
let output = input.reduce((acc, curr)=>{
let {id} = curr;
let majorVersion = 'name' + id.split('.')[0];
if(!acc[majorVersion]) acc[majorVersion]= [];
acc[majorVersion].push(curr);
return acc;
},{})
console.log(output)
function getInput(){
return [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
One solution with RegEx for finer control as it would differentiate easily between 1 and 11.
Also this will make sure that even if the same version comes in end(say 1.9 in end) it will put it back in data1.
let newArr2 = ({ results }) =>
results.reduce((acc, item) => {
let key = "data" + /^(\d+)\.?.*/.exec(item.id)[1];
let found = acc.find(i => key in i);
found ? found[key].push(item) : acc.push({ [key]: [item] });
return acc;
}, []);
This is my json:
{
"senderName": "ifelse",
"message": "Hi",
"groups": [
{
"id": 14,
"groupname": "Angular",
"contactgroups": [
{
"id": 1,
"contact": {
"id": 1,
"gsm": "123456789"
}
},
{
"id": 3,
"contact": {
"id": 2,
"gsm": "111111111"
}
}],
"select": true
}],
"draftData": {
"contacts": [
]
}
}
How to make the above json into:
[{phoneno: 123456789; sender: ifelse ; message: Hi},{phoneno: 11111111; sender: ifelse ; message: Hi}]
I want to take phoneno data from gsm object key
Which is best method to do this? for or forEach or anyother?
I guess, this is what you want. Use map to convert contactgroups to new array with phoneno.
var data = {
"senderName": "ifelse",
"message": "Hi",
"groups": [{
"id": 14,
"groupname": "Angular",
"contactgroups": [{
"id": 1,
"contact": {
"id": 1,
"gsm": "123456789"
}
},
{
"id": 3,
"contact": {
"id": 2,
"gsm": "111111111"
}
}
],
"select": true
}],
"draftData": {
"contacts": []
}
}
var result = data.groups[0].contactgroups.map(i => {
return {
phoneno: i.contact.gsm,
sender: data.senderName,
message: data.message
}
})
console.log(result);
I have an Object as below :
{"user": {
"name": "Harry Peter",
"phoneNumber": "12345",
"products": [
{
"type": "card",
"accountId": "5299367",
},
{
"type": "Loan",
"accountId": "5299365",
},
{
"type": "card",
"accountId": "8299388",
},
]}
}
What I need to find out if the user has both loan and card or just loan as user product.
Is there any built in function in javascript or angular to find it.
is someone has any suggestion how to do it. Please help.
You could use the filter array method.
var obj = {
"user": {
"name": "Harry Peter",
"phoneNumber": "12345",
"products": [
{
"type": "card",
"accountId": "5299367",
},
{
"type": "Loan",
"accountId": "5299365",
},
{
"type": "card",
"accountId": "8299388",
},
]
}
};
var loans = obj.user.products.filter(function(product){
return product.type === "Loan";
});
console.log("Loans: " + loans.length);
// supposing that the user has either a Loan or a card. You could
// easily now find out if the user has only loans as below:
if(loans.length === obj.user.products.length){
console.log("The user has only loans");
}else{
var cards = obj.user.products.length - loans.length;
console.log("The user has "+loans.length+" Loan(s) and "+ cards+ " Card(s).");
}
For further info about this method, please have a look here.
What I need to find out if the user has both loan and card or just
loan as user product.
Based on the above snippet, by using the filter method and comparing the length of the loans with the length of the products, you can answer you question.
You can loop over products and get unique types
var data = {
"user": {
"name": "Harry Peter",
"phoneNumber": "12345",
"products": [{
"type": "card",
"accountId": "5299367",
}, {
"type": "Loan",
"accountId": "5299365",
}, {
"type": "card",
"accountId": "8299388",
}, ]
}
}
var result= data.user.products.reduce(function(p,c){
if(p.indexOf(c.type)<0) p.push(c.type)
return p;
}, [])
console.log(result)
You can try following
var obj = {
"user": {
"name": "Harry Peter",
"phoneNumber": "12345",
"products": [{
"type": "card",
"accountId": "5299367",
}, {
"type": "Loan",
"accountId": "5299365",
}, {
"type": "card",
"accountId": "8299388",
}, ]
}
};
var results = {};
obj.user.products.reduce(function(oldval, item) {
oldval[item.type] = true;
return oldval;
}, results);
console.log(results.card && results.Loan); // paints true
// Additionally, results have all the information about the unique value for type, hence, can be used as per the need
Same Iteration solution, but immediately gives you if type is different from Loan.
var obj = {"user": {
"name": "Harry Peter",
"phoneNumber": "12345",
"products": [
{
"type": "card",
"accountId": "5299367",
},
{
"type": "Loan",
"accountId": "5299365",
},
{
"type": "card",
"accountId": "8299388",
},
]}
};
function haveDifferentProducts(products){
var isDiff = false;
products.forEach(function(product){
isDiff = product.type != "Loan"; //checks if type not loan
});
return isDiff;
}
console.log(haveDifferentProducts(obj.user.products))
Use Array filter() method.
Working demo :
var jsonObj = {
"user": {
"name": "Harry Peter",
"phoneNumber": "12345",
"products": [
{
"type": "card",
"accountId": "5299367",
},
{
"type": "Loan",
"accountId": "5299365",
},
{
"type": "card",
"accountId": "8299388",
},
]
}
};
var totalLoan = jsonObj.user.products.filter(function(item){
return item.type == "Loan";
});
var totalCards = jsonObj.user.products.filter(function(item){
return item.type == "card";
});
if(totalCards.length < 1 && totalLoan.length < 0) {
console.log("Only loan");
} else if (totalCards.length > 0 && totalLoan.length < 1) {
console.log("Only card");
} else {
console.log("Both card as well as loan");
}