Nested array within nested object - javascript

I had an object whose structure is
const data = {
"message": "fetch responces successfully",
"responce": [
{
"created_AT": "Mon, 03 Jan 2022 17:39:24 GMT",
"created_BY": "avinash",
"dateTime": "Mon, 03 Jan 2022 17:39:24 GMT",
"deleted_BY": "",
"flag": 0,
"project_ID": "infobot1234",
"responce": {
"uttence_test_heading": [
{
"buttons": [
{
"payload": "/my_localities",
"title": "savings"
},
{
"payload": "/my_localities12333qqqwq",
"title": "current"
},
{
"payload": "/fruits",
"title": "platinum"
}
]
},
{
"title": "Test Heading"
}
]
},
"responce_ID": "6bbb20d6-7f71-408a-a78a-bab39a30016f",
"responce_name": "uttence_test_heading",
"updated_BY": "",
"user_ID": "av1234"
},
{
"created_AT": "Tue, 04 Jan 2022 17:49:36 GMT",
"created_BY": "avinash",
"dateTime": "Tue, 04 Jan 2022 17:49:36 GMT",
"deleted_BY": "",
"flag": 0,
"project_ID": "infobot1234",
"responce": {
"utter_content": [
{
"text": "text_title for buttonqwqwq"
}
]
},
"responce_ID": "81d699ee-3e78-4356-b703-af095d91e36b",
"responce_name": "utter_txt1234",
"updated_BY": "",
"user_ID": "av1234"
},
{
"created_AT": "Thu, 13 Jan 2022 18:06:39 GMT",
"created_BY": "avinash",
"dateTime": "Thu, 13 Jan 2022 18:06:39 GMT",
"deleted_BY": "",
"flag": 0,
"project_ID": "infobot1234",
"responce": {
"uttence_text_heading": [
{
"buttons": [
{
"payload": "/my_localities",
"title": "savings"
},
{
"payload": "/my_localities12333qqqwq",
"title": "current"
},
{
"payload": "/test",
"title": "premium"
}
]
},
{
"title": "Text Heading"
}
]
},
"responce_ID": "bb6b0005-bbd4-49a1-8b25-58e0768800a1",
"responce_name": "uttence_text_heading",
"updated_BY": "",
"user_ID": "av1234"
},
{
"created_AT": "Thu, 13 Jan 2022 20:13:54 GMT",
"created_BY": "avinash",
"dateTime": "Thu, 13 Jan 2022 20:13:54 GMT",
"deleted_BY": "",
"flag": 0,
"project_ID": "infobot1234",
"responce": {
"uttence_heading_test": [
{
"buttons": [
{
"payload": "/my_localities",
"title": "savings"
},
{
"payload": "/fruits",
"title": "current"
},
{
"payload": "/undefined",
"title": "premium"
}
]
},
{
"title": "heading test"
}
]
},
"responce_ID": "7aeb2a42-a5f8-464d-832d-47cee4cfdb38",
"responce_name": "uttence_heading_test",
"updated_BY": "",
"user_ID": "av1234"
}
],
"status_code": 0
}
I was able to extract below array of objects by using data.responce.map(responce => responce.responce)
[{
uttence_test_heading: [{
buttons: [{
payload: "/my_localities",
title: "savings"
}, {
payload: "/my_localities12333qqqwq",
title: "current"
}, {
payload: "/fruits",
title: "platinum"
}]
}, {
title: "Test Heading"
}]
}, {
utter_content: [{
text: "text_title for buttonqwqwq"
}]
}, {
uttence_text_heading: [{
buttons: [{
payload: "/my_localities",
title: "savings"
}, {
payload: "/my_localities12333qqqwq",
title: "current"
}, {
payload: "/test",
title: "premium"
}]
}, {
title: "Text Heading"
}]
}, {
uttence_heading_test: [{
buttons: [{
payload: "/my_localities",
title: "savings"
}, {
payload: "/fruits",
title: "current"
}, {
payload: "/undefined",
title: "premium"
}]
}, {
title: "heading test"
}]
}]
Now I want to construct an array of objects whose structure is something like below
This is my expected result, but I am stuck since the uttence_name is a key and it is different for each object so could someone please guide me through how can I acheive my expected result. Please Help !
[{uttence_name: ' uttence_test_heading',buttons: ['savings','current','platinum'],text: '',responce_ID:'6bbb20d6-7f71-408a-a78a-bab39a30016f'},
{uttence_name: 'utter_content',buttons: '',text: 'text_title for buttonqwqwq',responce_ID:'81d699ee-3e78-4356-b703-af095d91e36b'},
{uttence_name:'uttence_text_heading',buttons:['savings','current','premium'],text: '',responce_ID:'bb6b0005-bbd4-49a1-8b25-58e0768800a1'}]

You can chain a second map and obtain the desired result. But my answer assumes that the arrays only have a single item in them.
Also, I didn't quite understand what you wanted to do with the buttons so I've kept them as an array.
You can run the snippet below to see if you're getting the desired output.
const data={message:"fetch responces successfully",responce:[{created_AT:"Mon, 03 Jan 2022 17:39:24 GMT",created_BY:"avinash",dateTime:"Mon, 03 Jan 2022 17:39:24 GMT",deleted_BY:"",flag:0,project_ID:"infobot1234",responce:{uttence_test_heading:[{buttons:[{payload:"/my_localities",title:"savings",},{payload:"/my_localities12333qqqwq",title:"current",},{payload:"/fruits",title:"platinum",},],},{title:"Test Heading",},],},responce_ID:"6bbb20d6-7f71-408a-a78a-bab39a30016f",responce_name:"uttence_test_heading",updated_BY:"",user_ID:"av1234",},{created_AT:"Tue, 04 Jan 2022 17:49:36 GMT",created_BY:"avinash",dateTime:"Tue, 04 Jan 2022 17:49:36 GMT",deleted_BY:"",flag:0,project_ID:"infobot1234",responce:{utter_content:[{text:"text_title for buttonqwqwq",},],},responce_ID:"81d699ee-3e78-4356-b703-af095d91e36b",responce_name:"utter_txt1234",updated_BY:"",user_ID:"av1234",},{created_AT:"Thu, 13 Jan 2022 18:06:39 GMT",created_BY:"avinash",dateTime:"Thu, 13 Jan 2022 18:06:39 GMT",deleted_BY:"",flag:0,project_ID:"infobot1234",responce:{uttence_text_heading:[{buttons:[{payload:"/my_localities",title:"savings",},{payload:"/my_localities12333qqqwq",title:"current",},{payload:"/test",title:"premium",},],},{title:"Text Heading",},],},responce_ID:"bb6b0005-bbd4-49a1-8b25-58e0768800a1",responce_name:"uttence_text_heading",updated_BY:"",user_ID:"av1234",},{created_AT:"Thu, 13 Jan 2022 20:13:54 GMT",created_BY:"avinash",dateTime:"Thu, 13 Jan 2022 20:13:54 GMT",deleted_BY:"",flag:0,project_ID:"infobot1234",responce:{uttence_heading_test:[{buttons:[{payload:"/my_localities",title:"savings",},{payload:"/fruits",title:"current",},{payload:"/undefined",title:"premium",},],},{title:"heading test",},],},responce_ID:"7aeb2a42-a5f8-464d-832d-47cee4cfdb38",responce_name:"uttence_heading_test",updated_BY:"",user_ID:"av1234",},],status_code:0,}
const result = data.responce
.map((res) => ({...res.responce, responce_ID: res.responce_ID }))
.map((obj) => ({
utterance_name: Object.keys(obj)[0],
text: Object.values(obj)[0][0].text || "",
buttons: Object.values(obj)[0][0].buttons?.map((btn) => btn.title) || "",
responce_ID: obj.responce_ID
}));
console.log(result);

Here is the required result based upon the data you have given. In the code, the best case scenario is, it checks whether you have object containing text or not and then adds the data accordingly. It also has response_ID
const data={message:"fetch responces successfully",responce:[{created_AT:"Mon, 03 Jan 2022 17:39:24 GMT",created_BY:"avinash",dateTime:"Mon, 03 Jan 2022 17:39:24 GMT",deleted_BY:"",flag:0,project_ID:"infobot1234",responce:{uttence_test_heading:[{buttons:[{payload:"/my_localities",title:"savings",},{payload:"/my_localities12333qqqwq",title:"current",},{payload:"/fruits",title:"platinum",},],},{title:"Test Heading",},],},responce_ID:"6bbb20d6-7f71-408a-a78a-bab39a30016f",responce_name:"uttence_test_heading",updated_BY:"",user_ID:"av1234",},{created_AT:"Tue, 04 Jan 2022 17:49:36 GMT",created_BY:"avinash",dateTime:"Tue, 04 Jan 2022 17:49:36 GMT",deleted_BY:"",flag:0,project_ID:"infobot1234",responce:{utter_content:[{text:"text_title for buttonqwqwq",},],},responce_ID:"81d699ee-3e78-4356-b703-af095d91e36b",responce_name:"utter_txt1234",updated_BY:"",user_ID:"av1234",},{created_AT:"Thu, 13 Jan 2022 18:06:39 GMT",created_BY:"avinash",dateTime:"Thu, 13 Jan 2022 18:06:39 GMT",deleted_BY:"",flag:0,project_ID:"infobot1234",responce:{uttence_text_heading:[{buttons:[{payload:"/my_localities",title:"savings",},{payload:"/my_localities12333qqqwq",title:"current",},{payload:"/test",title:"premium",},],},{title:"Text Heading",},],},responce_ID:"bb6b0005-bbd4-49a1-8b25-58e0768800a1",responce_name:"uttence_text_heading",updated_BY:"",user_ID:"av1234",},{created_AT:"Thu, 13 Jan 2022 20:13:54 GMT",created_BY:"avinash",dateTime:"Thu, 13 Jan 2022 20:13:54 GMT",deleted_BY:"",flag:0,project_ID:"infobot1234",responce:{uttence_heading_test:[{buttons:[{payload:"/my_localities",title:"savings",},{payload:"/fruits",title:"current",},{payload:"/undefined",title:"premium",},],},{title:"heading test",},],},responce_ID:"7aeb2a42-a5f8-464d-832d-47cee4cfdb38",responce_name:"uttence_heading_test",updated_BY:"",user_ID:"av1234",},],status_code:0,};
let newObject = [];
data.responce.forEach((item) => {
// We will get each item here now
// Assuming object of item.responce will come always
const objectName = Object.keys(item.responce)[0];
const dataToPush = {
'responce_ID': item.responce_ID,
'uttence_name': objectName,
'buttons': item.responce[objectName][0].buttons ? item.responce[objectName][0].buttons.map(data => data.title) : '',
'text': item.responce[objectName].find(data => data.hasOwnProperty('text')) ? item.responce[objectName].map(value => value.text)[0] : ''
};
// Finally adding the item to the array to give the final output
newObject.push(dataToPush);
});
console.log(newObject);

Related

How do I generate html file using JSON object generated from libnmap library

I am using the libnmap library to extract data for various IPs. The data comes in the form of a JSON object. I want to generate an HTML file using the JSON object. There are multiple fields. I do not know how to design an HTML page for the below-given json object to fit this much of content corresponding to various fields.
How can I approach to do this? Any code or any help would be appreciated.
This is my json:
{
"IP1": {
"item": {
"scanner": "nmap",
"args": "nmap --host-timeout=120s -T4 -oX - -p1-1024 20.102.61.164",
"start": "1676406830",
"startstr": "Tue Feb 14 20:33:50 2023",
"version": "7.80",
"xmloutputversion": "1.04"
},
"scaninfo": [
{
"item": {
"type": "connect",
"protocol": "tcp",
"numservices": "1024",
"services": "1-1024"
}
}
],
"verbose": [
{
"item": {
"level": "0"
}
}
],
"debugging": [
{
"item": {
"level": "0"
}
}
],
"runstats": [
{
"finished": [
{
"item": {
"time": "1676406832",
"timestr": "Tue Feb 14 20:33:52 2023",
"elapsed": "2.07",
"summary": "Nmap done at Tue Feb 14 20:33:52 2023; 1 IP address (0 hosts up) scanned in 2.07 seconds",
"exit": "success"
}
}
],
"hosts": [
{
"item": {
"up": "0",
"down": "1",
"total": "1"
}
}
]
}
]
},
"IP2": {
"item": {
"scanner": "nmap",
"args": "nmap --host-timeout=120s -T4 -oX - -p1-1024 157.56.181.249",
"start": "1676406830",
"startstr": "Tue Feb 14 20:33:50 2023",
"version": "7.80",
"xmloutputversion": "1.04"
},
"scaninfo": [
{
"item": {
"type": "connect",
"protocol": "tcp",
"numservices": "1024",
"services": "1-1024"
}
}
],
"verbose": [
{
"item": {
"level": "0"
}
}
],
"debugging": [
{
"item": {
"level": "0"
}
}
],
"runstats": [
{
"finished": [
{
"item": {
"time": "1676406832",
"timestr": "Tue Feb 14 20:33:52 2023",
"elapsed": "2.08",
"summary": "Nmap done at Tue Feb 14 20:33:52 2023; 1 IP address (0 hosts up) scanned in 2.08 seconds",
"exit": "success"
}
}
],
"hosts": [
{
"item": {
"up": "0",
"down": "1",
"total": "1"
}
}
]
}
]
}
}

How to combine common data in JSON object of Map()?

I have some JSON Data Like This:
{
"+2555970315763":{
"uid": "u9weKk62GvXu4Yf66HM2TFXDL5S2",
"phoneNumber": "+2555970315763",
"lastTime": "Mon, 14 Feb 2022 09:40:32 GMT"
},
"+2555970605736":{
"uid": "n3qGtqMWqVXGyZMSFz7HqwtfTDB3",
"phoneNumber": "+2555970605736",
"lastTime": "Mon, 14 Feb 2022 05:32:53 GMT"
},
"+2555973055799":{
"uid": "hGHq2TLCkeWsCWOZ0KdSI6mKbvp2",
"phoneNumber": "+2555973055799",
"lastTime": "Mon, 21 Feb 2022 05:25:46 GMT",
"usage": [
{
"firstTime": "18:04:34",
"count": 1,
"date": "2022-02-19"
},
{
"firstTime": "14:53:08",
"count": 6,
"date": "2022-02-21"
},
{
"count": 4,
"date": "2022-02-22",
"firstTime": "12:53:56"
},
{
"date": "2022-02-25",
"count": 4,
"firstTime": "12:12:03"
},
{
"firstTime": "12:35:04",
"date": "2022-02-26",
"count": 34
},
{
"count": 31,
"firstTime": "11:32:03",
"date": "2022-02-27"
}
]
},
"+2555974235764":{
"uid": "uUWJvN5XVwWGfNiC6UuwlmVVTO73",
"phoneNumber": "+2555974235764",
"lastTime": "Wed, 16 Feb 2022 06:04:54 GMT",
"usage": [
{
"count": 2,
"date": "2022-02-16",
"firstTime": "12:15:38"
},
{
"date": "2022-02-17",
"firstTime": "11:45:19",
"count": 43
},
{
"count": 148,
"firstTime": "11:33:53",
"date": "2022-02-19"
},
{
"count": 127,
"firstTime": "11:42:46",
"date": "2022-02-20",
"dow": "Sunday"
},
{
"firstTime": "12:18:28",
"count": 42,
"date": "2022-02-22",
}
]
},
"+2555979295712":{
"uid": "Cx63RRHQYpMMwfAbi0ebqledk5G3",
"phoneNumber": "+2555979295712",
"lastTime": "Tue, 01 Mar 2022 13:18:23 GMT",
},
"+2555970875726":{
"uid": "I5I3SFgZT3MAxomDHrPGq17OMcO2",
"phoneNumber": "+2555970875726",
"lastTime": "Tue, 01 Mar 2022 15:43:43 GMT",
},
"+2555970125770":{
"uid": "y9IcP0S6uHcOjPk0deXbuXZC4VA3",
"phoneNumber": "+2555970125770",
"lastTime": "Tue, 25 Jan 2022 09:38:27 GMT",
},
"+2555970335754":{
"uid": "gS2RkZdBlHZNOIYQUXB1iPfOkQ33",
"phoneNumber": "+2555970335754",
"lastTime": "Fri, 18 Feb 2022 07:40:32 GMT",
},
"+2555974475787":{
"uid": "QfSNsAMob8SXYWFB8TmgC0WMAXY2",
"phoneNumber": "+2555974475787",
"lastTime": "Fri, 11 Feb 2022 08:44:47 GMT",
},
"+2555974725740":{
"uid": "9y4unCW5PHRA0AjcVZdHFXh9thy1",
"phoneNumber": "+2555974725740",
"lastTime": "Mon, 21 Feb 2022 13:57:27 GMT",
}
}
I want to merge some of the phonenumber data like +2555973055799 and +2555974235764, I the for example: they both have objects with date:2022-02-19 so, the resultant object after merging should be like:
{
"firstTime": "11:33:53",
"count": 149,
"date": "2022-02-19"
},
count should be sum of both objects from phonenumbers ad firstTime should be time which is first. and uid, phone number should be concatinated, lastTime should be which is greater of two times?
The remaining phonenumbers data should be unchanged, only these two objects data should be merged,
How should I do that?
can anyone please help with this?
I am not sure if i understand your question correctly, but let's give it a try.
So, you would like to merge datas according to the date of usage. If 2 or more json objects was used on the same date, then you would like to to see the date, count and first time of use of these datas?
EDIT:
So, i created a prototype.
Maybe it is a little bit complicated solution, but i think it is good for a start.
I separated every object with usage data, then i looked for date duplicates, i stored both uid and the same date. Then i looked up for the count's and compared the firstTime datas and everything stored in the result variable.
Check console log for result.
var result = [] // we will store the result here
var dataWithUsage = [];
for (var i in obj) // iterate thru every data
if (obj[i].usage) // if data has usage property
{
dataWithUsage.push(obj[i]) // separate it from the main data structure
}
// console.log(dataWithUsage)
var usages = [] // we will collect every usage here
dataWithUsage.forEach(data => {
// console.log(data.usage, data.uid)
data.usage.forEach(element => {
usages.push({ date: element.date, uid: data.uid })
});
});
// console.log(usages)
// we will compare every usage and we try to do it only once
for (let i = 0; i < usages.length; i++) {
for (let j = i + 1; j < usages.length; j++) {
// console.log(usages[i], "vs" , usages[j])
if (usages[i].date == usages[j].date) {
result.push({ date: usages[i].date, uid1: usages[i].uid, uid2: usages[j].uid })
}
}
}
// at this point in the results we have our uid's with dates. Now we can do the data merge
result.forEach(element => {
var uid1Index = dataWithUsage.findIndex(object => object.uid == element.uid1)
var uid2Index = dataWithUsage.findIndex(object => object.uid == element.uid2) // we got the 2 objects for data merge
var count = 0
var firstTime
let usageIndexofuid1 = dataWithUsage[uid1Index].usage.findIndex(elem => elem.date == element.date)
let usageIndexofuid2 = dataWithUsage[uid2Index].usage.findIndex(elem => elem.date == element.date)
count = dataWithUsage[uid1Index].usage[usageIndexofuid1].count + dataWithUsage[uid2Index].usage[usageIndexofuid2].count
// console.log(dataWithUsage[uid1Index].usage[usageIndexofuid1].firstTime, dataWithUsage[uid2Index].usage[usageIndexofuid2].firstTime)
// console.log(dataWithUsage[uid1Index].usage[usageIndexofuid1].firstTime > dataWithUsage[uid2Index].usage[usageIndexofuid2].firstTime)
firstTime = ((dataWithUsage[uid1Index].usage[usageIndexofuid1].firstTime < dataWithUsage[uid2Index].usage[usageIndexofuid2].firstTime) ? dataWithUsage[uid1Index].usage[usageIndexofuid1].firstTime : dataWithUsage[uid2Index].usage[usageIndexofuid2].firstTime)
// console.log(firstTime,"fistTime")
// console.log(count,"count")
element.count = count
element.firstTime = firstTime
});
console.log("result")
console.log(result)
https://jsfiddle.net/peaq6cb3/

How to find the max occurrence (highest count) of a value in an Array of Objects in JSON format?

I have the data in the following format:
[
{
"product": "Term Insurance",
"ViewTime": "Wed Jan 20 14:13:05 IST 2021",
"userBought": true,
"userLocation": {
"loaded": true,
"userAllowed": true,
"coordinates": {
"lng": 70.8856,
"lat": 19.0748
}
},
"category": "Health Insurance"
},
{
"product": "Car Insurance",
"ViewTime": "Wed Jan 20 15:40:31 IST 2021",
"userBought": true,
"userLocation": {
"loaded": true,
"userAllowed": true,
"coordinates": {
"lng": 70.8856,
"lat": 19.0748
}
},
"category": "Motor Insurance"
},
{
"product": "Car Insurance",
"ViewTime": "Wed Jan 20 15:42:52 IST 2021",
"userBought": true,
"userLocation": {
"loaded": true,
"userAllowed": true,
"coordinates": {
"lng": 70.8856,
"lat": 19.0748
}
},
"category": "Motor Insurance"
}]
I want to map through the array and calculate the maxCategory and maxProduct from the number of occurrences using Javascript. Like here the maxCategory would be "Motor Insurance" and maxProduct would be "Car Insurance". Is there any clean, efficient way to do it?
You can count the properties and then apply reduce method, try this:
let cars = [
{
"product": "Term Insurance",
"ViewTime": "Wed Jan 20 14:13:05 IST 2021",
"userBought": true,
"userLocation": {
"loaded": true,
"userAllowed": true,
"coordinates": {
"lng": 70.8856,
"lat": 19.0748
}
},
"category": "Health Insurance"
},
{
"product": "Car Insurance",
"ViewTime": "Wed Jan 20 15:40:31 IST 2021",
"userBought": true,
"userLocation": {
"loaded": true,
"userAllowed": true,
"coordinates": {
"lng": 70.8856,
"lat": 19.0748
}
},
"category": "Motor Insurance"
},
{
"product": "Car Insurance",
"ViewTime": "Wed Jan 20 15:42:52 IST 2021",
"userBought": true,
"userLocation": {
"loaded": true,
"userAllowed": true,
"coordinates": {
"lng": 70.8856,
"lat": 19.0748
}
},
"category": "Motor Insurance"
}]
let counterCategories = {}
for (property of cars){
counterCategories[property.category] = 1 + (counterCategories[property.category] || 0)
}
console.log(counterCategories)
let entries = Object.entries(counterCategories);
let result = entries.reduce((acc, el) => acc[1] < el[1] ? el[0] : acc[0])
console.log('maxCategory: ' + result)
Since you are looking for an efficient way to do this. I've used a single loop to find out the result. You can check this.
const data = [
{
product: 'Term Insurance',
ViewTime: 'Wed Jan 20 14:13:05 IST 2021',
userBought: true,
userLocation: {
loaded: true,
userAllowed: true,
coordinates: {
lng: 70.8856,
lat: 19.0748,
},
},
category: 'Health Insurance',
},
{
product: 'Car Insurance',
ViewTime: 'Wed Jan 20 15:40:31 IST 2021',
userBought: true,
userLocation: {
loaded: true,
userAllowed: true,
coordinates: {
lng: 70.8856,
lat: 19.0748,
},
},
category: 'Motor Insurance',
},
{
product: 'Car Insurance',
ViewTime: 'Wed Jan 20 15:42:52 IST 2021',
userBought: true,
userLocation: {
loaded: true,
userAllowed: true,
coordinates: {
lng: 70.8856,
lat: 19.0748,
},
},
category: 'Motor Insurance',
},
];
let [maxProductCount, maxCategoryCount, maxProduct, maxCategory, tmpObj] = [0, 0, null, null, {}];
data.forEach(({ product, category }) => {
tmpObj[product] = (tmpObj[product] || 0) + 1;
tmpObj[category] = (tmpObj[category] || 0) + 1;
if (tmpObj[product] > maxProductCount) {
maxProductCount = tmpObj[product];
maxProduct = product;
}
if (tmpObj[category] > maxCategoryCount) {
maxCategoryCount = tmpObj[category];
maxCategory = category;
}
});
console.log({ maxProduct, maxCategory });
Have a look to the lodash countBy method:
let data = [...]
_.countBy(data, (item) => item.category);
// {"Health Insurance": 1, "Motor Insurance": 2}
_.countBy(data, (item) => item.product);
// {"Term Insurance": 1, "Car Insurance": 2}

javascript sorting array of object according to date in string with some null values [duplicate]

This question already has answers here:
How to sort array by date when some dates are null
(2 answers)
Closed 2 years ago.
I have an array of objects, I want to sort this array according to date which is in string format. The problem is this array can have blank values for a date, the code I am using works for array without blank values, but with blank values, it doesn't return properly sorted array.
This is array eg-
var array =
[{
"_id" : "5f6a0c223932cd1f7ae1d48c",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Fri Oct 16 2020 00:00:00"
},
{
"_id" : "5f6990b94130056cd6034091",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : ""
},
{
"_id" : "5f6a0c2a3932cd1f7ae1d48d",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Fri Nov 27 2020 00:00:00"
},
{
"_id" : "5f6a0c453932cd1f7ae1d48e",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Thu Oct 22 2020 00:00:00"
},
{
"_id" : "5f6a0c4d3932cd1f7ae1d48f",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Thu Nov 19 2020 00:00:00"
},
{
"_id" : "5f6a0c5a3932cd1f7ae1d490",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Thu Dec 03 2020 00:00:00"
},
{
"_id" : "5f1bd948a1db382540356394",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Mon Jul 13 2020 20:30:00"
},
{
"_id" : "5f698ca54130056cd603408e",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Fri Sep 25 2020 00:00:00"
},
{
"_id" : "5f698cae4130056cd603408f",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Thu Sep 24 2020 00:00:00"
},
{
"_id" : "5f698cb64130056cd6034090",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Wed Sep 23 2020 00:00:00"
},
{
"_id" : "5f6a0c163932cd1f7ae1d48b",
"user_id" : "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date" : "Sun Nov 08 2020 00:00:00"
}]
The code I am using is -
array.sort(function compare(a, b) {
var dateA = new Date(a.current_term_renewal_date);
var dateB = new Date(b.current_term_renewal_date);
return dateA - dateB;
});
The expected result-
[{
_id: "5f1bd948a1db382540356394",
current_term_renewal_date: "Mon Jul 13 2020 20:30:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f698cb64130056cd6034090",
current_term_renewal_date: "Wed Sep 23 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f698cae4130056cd603408f",
current_term_renewal_date: "Thu Sep 24 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f698ca54130056cd603408e",
current_term_renewal_date: "Fri Sep 25 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f6a0c223932cd1f7ae1d48c",
current_term_renewal_date: "Fri Oct 16 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f6a0c453932cd1f7ae1d48e",
current_term_renewal_date: "Thu Oct 22 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f6a0c163932cd1f7ae1d48b",
current_term_renewal_date: "Sun Nov 08 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f6a0c4d3932cd1f7ae1d48f",
current_term_renewal_date: "Thu Nov 19 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f6a0c2a3932cd1f7ae1d48d",
current_term_renewal_date: "Fri Nov 27 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f6a0c5a3932cd1f7ae1d490",
current_term_renewal_date: "Thu Dec 03 2020 00:00:00",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}, {
_id: "5f6990b94130056cd6034091",
current_term_renewal_date: "",
user_id: "5e82f6d1ca6f2a3b4d2212a1"
}]
This is the link for jsfiddle
JS Fiddle Code
When date is empty, the resultant date object is "Invalid Date" ... so, the easiest remedy, and to move empty dates to the end
var dateA = +new Date(a.current_term_renewal_date) || Number.MAX_SAFE_INTEGER;
same for dateB
Note the + before new, to get a Number, an invalid date results in NaN ... and NaN || Number.MAX_SAFE_INTEGER === Number.MAX_SAFE_INTEGER
You could use Infinity too - anything that is a LARGE number will do
var array = [{
"_id": "5f6a0c223932cd1f7ae1d48c",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Fri Oct 16 2020 00:00:00"
},
{
"_id": "5f6990b94130056cd6034091",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": ""
},
{
"_id": "5f6a0c2a3932cd1f7ae1d48d",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Fri Nov 27 2020 00:00:00"
},
{
"_id": "5f6a0c453932cd1f7ae1d48e",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Thu Oct 22 2020 00:00:00"
},
{
"_id": "5f6a0c4d3932cd1f7ae1d48f",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Thu Nov 19 2020 00:00:00"
},
{
"_id": "5f6a0c5a3932cd1f7ae1d490",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Thu Dec 03 2020 00:00:00"
},
{
"_id": "5f1bd948a1db382540356394",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Mon Jul 13 2020 20:30:00"
},
{
"_id": "5f698ca54130056cd603408e",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Fri Sep 25 2020 00:00:00"
},
{
"_id": "5f698cae4130056cd603408f",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Thu Sep 24 2020 00:00:00"
},
{
"_id": "5f698cb64130056cd6034090",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Wed Sep 23 2020 00:00:00"
},
{
"_id": "5f6a0c163932cd1f7ae1d48b",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Sun Nov 08 2020 00:00:00"
}
]
array.sort(function compare(a, b) {
var dateA = +new Date(a.current_term_renewal_date) || Number.MAX_SAFE_INTEGER;
var dateB = +new Date(b.current_term_renewal_date) || Number.MAX_SAFE_INTEGER;
return dateA - dateB;
});
console.log("result", array)
for (var idx in array)
{
var row = array[idx];
if (!row.current_term_renewal_date)
{
row.sortable = 0;
continue;
}
var date = row.current_term_renewal_date.split('/');
row.sortable = 10000 * parseInt(date[2]) + 100 * parseInt(date[0]) + parseInt(date[1]); // year, month, day
}
array.sort(function(a, b)
{
return a.sortable > b.sortable ? 1 : a.sortable < b.sortable ? -1 : 0;
});
var result = [];
for (var idx=0; idx < array.length; idx++)
result.push(array[idx].current_term_renewal_date);
console.log(result.join(", "));
Do Somthing Like This:
https://jsfiddle.net/p3f8xq46/
Check the validity of date object and run the code return the value I have done a similar thing below for you
var array = [{
"_id": "5f6a0c223932cd1f7ae1d48c",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Fri Oct 16 2020 00:00:00"
},
{
"_id": "5f6990b94130056cd6034091",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": ""
},
{
"_id": "5f6a0c2a3932cd1f7ae1d48d",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Fri Nov 27 2020 00:00:00"
},
{
"_id": "5f6a0c453932cd1f7ae1d48e",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Thu Oct 22 2020 00:00:00"
},
{
"_id": "5f6a0c4d3932cd1f7ae1d48f",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Thu Nov 19 2020 00:00:00"
},
{
"_id": "5f6a0c5a3932cd1f7ae1d490",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Thu Dec 03 2020 00:00:00"
},
{
"_id": "5f1bd948a1db382540356394",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Mon Jul 13 2020 20:30:00"
},
{
"_id": "5f698ca54130056cd603408e",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Fri Sep 25 2020 00:00:00"
},
{
"_id": "5f698cae4130056cd603408f",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Thu Sep 24 2020 00:00:00"
},
{
"_id": "5f698cb64130056cd6034090",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Wed Sep 23 2020 00:00:00"
},
{
"_id": "5f6a0c163932cd1f7ae1d48b",
"user_id": "5e82f6d1ca6f2a3b4d2212a1",
"current_term_renewal_date": "Sun Nov 08 2020 00:00:00"
}
]
array.sort(function compare(a, b) {
var dateA = new Date(a.current_term_renewal_date);
var dateB = new Date(b.current_term_renewal_date);
if (!dateA.toJSON()) {
return 1;
}
if (!dateB.toJSON()) {
return -1;
}
return dateA - dateB;
});
console.log("result", array)
You need to capture this case separatly.
Return -1 if the b Date is empty string or does not exists:
if (!b.current_term_renewal_date || b.current_term_renewal_date === '') return -1;
Another option is to check if the Date is valid but this would only work if it is an empty string.
You could also check your result for validity using isNaN()
You could take the delta of the wanted negated property and move falsy values to bottom.
const
array = [{ _id: "5f6a0c223932cd1f7ae1d48c", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Fri Oct 16 2020 00:00:00" }, { _id: "5f6990b94130056cd6034091", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "" }, { _id: "5f6a0c2a3932cd1f7ae1d48d", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Fri Nov 27 2020 00:00:00" }, { _id: "5f6a0c453932cd1f7ae1d48e", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Thu Oct 22 2020 00:00:00" }, { _id: "5f6a0c4d3932cd1f7ae1d48f", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Thu Nov 19 2020 00:00:00" }, { _id: "5f6a0c5a3932cd1f7ae1d490", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Thu Dec 03 2020 00:00:00" }, { _id: "5f1bd948a1db382540356394", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Mon Jul 13 2020 20:30:00" }, { _id: "5f698ca54130056cd603408e", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Fri Sep 25 2020 00:00:00" }, { _id: "5f698cae4130056cd603408f", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Thu Sep 24 2020 00:00:00" }, { _id: "5f698cb64130056cd6034090", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Wed Sep 23 2020 00:00:00" }, { _id: "5f6a0c163932cd1f7ae1d48b", user_id: "5e82f6d1ca6f2a3b4d2212a1", current_term_renewal_date: "Sun Nov 08 2020 00:00:00" }]
array.sort((a, b) => {
const
dateA = new Date(a.current_term_renewal_date),
dateB = new Date(b.current_term_renewal_date);
return !a.current_term_renewal_date - !b.current_term_renewal_date
|| dateA - dateB;
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

What's the best way to group a JSON object by a certain value?

I want to be able to display data in an React application like so:
Today
- Batman entered the watchtower at 10:30am
- Batman entered the watchtower at 10:15am
- Wonder Woman entered the watchtower at 10:00am
Yesterday
- Flash entered the watchtower at 10:30am
- Green Lantern entered the watchtower at 10:15am
- Cyborg entered the watchtower at 10:00am
9th August 2018
- Aquaman entered the watchtower at 10:30am
The data being sent to me is an JSON Array of objects:
[{
"name": "Batman",
"secret_identity": "Bruce Wayne",
"timestamp": "1533983400" // Epoch timestamp equating to 11th August 2018 at 10:30am
},
{
"name": "Superman",
"secret_identity": "Clark Kent",
"timestamp": "1533982500" // Epoch timestamp equating to 11th August 2018 at 10:15am
},
{
"name": "Wonder Woman",
"secret_identity": "Diana Prince",
"timestamp": "1533981600" // Epoch timestamp equating to 11th August 2018 at 10:00am
},
{
"name": "Flash",
"secret_identity": "Wally West",
"timestamp": "1533897000" // Epoch timestamp equating to 10th August 2018 at 10:30am
},
{
"name": "Green Lantern",
"secret_identity": "Hal Jordan",
"timestamp": "1533896100" // Epoch timestamp equating to 10th August 2018 at 10:15am
},
{
"name": "Cyborg",
"secret_identity": "Victor Stone",
"timestamp": "1533895800" // Epoch timestamp equating to 10th August 2018 at 10:00am
},
{
"name": "Aquaman",
"secret_identity": "Arthur Curry",
"timestamp": "1533810600" // Epoch timestamp equating to 9th August 2018 at 10:30am
}]
I am not sure what's the best way to use this JSON Array to render the data in the way that I need. I thought I may need to process the data further in a new object like below but am not sure the best way to do so.
[{
"11-August-2018" : [{
"name": "Batman",
"secret_identity": "Bruce Wayne",
"timestamp": "1533983400" // 11th August 2018 at 10:30am
},
{
"name": "Superman",
"secret_identity": "Clark Kent",
"timestamp": "1533982500" // 11th August 2018 at 10:15am
},
{
"name": "Wonder Woman",
"secret_identity": "Diana Prince",
"timestamp": "1533981600" // 11th August 2018 at 10:00am
}],
"10-August-2018" : [{
"name": "Flash",
"secret_identity": "Wally West",
"timestamp": "1533897000" // 10th August 2018 at 10:30am
},
{
"name": "Green Lantern",
"secret_identity": "Hal Jordan",
"timestamp": "1533896100" // 10th August 2018 at 10:15am
},
{
"name": "Cyborg",
"secret_identity": "Victor Stone",
"timestamp": "1533895800" // 10th August 2018 at 10:00am
}],
"09-August-2018" : [{
"name": "Aquaman",
"secret_identity": "Arthur Curry",
"timestamp": "1533810600" // 9th August 2018 at 10:30am
}]
}]
Sorting, mapping, reducing. Gotta love es2018
(d => {
// a few utility methods
const dateFromEpoch = epochStr => new Date(new Date(0).setUTCSeconds(+epochStr));
const padLeft = n => `${n}`.padStart(2, "0");
const removeTime = dateTime => new Date(dateTime.toISOString().split("T")[0]);
const getDateLabel = dateTime => {
const now = removeTime(new Date());
const plainDate = removeTime(dateTime);
const dayDiff = Math.abs(Math.round(((plainDate - now) / 3600000) / 24));
return dayDiff < 1 ?
"Today" :
dayDiff === 1 ?
"Yesterday" :
`${dayDiff} Days ago`;
};
const heroicData = getHeroicData()
.sort((a, b) => +a.timestamp < +b.timestamp) // sort descending
.reduce(heroicReducer, {}); // create reshuffled object
// the heroic entry points
d.querySelector("#raw").textContent = JSON.stringify(heroicData, null, " ");
// create html output using a reducer
d.querySelector("#result").innerHTML = Object.keys(heroicData)
.reduce((reduced, day) =>
reduced.concat(`
<b>${day}</b>
<ul>
${heroicData[day].map(visit => `<li>${visit}</li>`).join("")}
</ul>`), [])
.join("");
function heroicReducer(reduced, heroicVisit) {
const dateTime = dateFromEpoch(heroicVisit.timestamp);
const reportKey = getDateLabel(dateTime);
const reportString = `<heroe>${
heroicVisit.name}</heroe> entered the watchtower at ${
padLeft(dateTime.getHours())}:${
padLeft(dateTime.getMinutes())}`;
if (reduced[reportKey]) {
reduced[reportKey].push(reportString)
} else {
reduced[reportKey] = [reportString];
}
return reduced;
}
function getHeroicData() {
return [{
"name": "Batman",
"secret_identity": "Bruce Wayne",
"timestamp": "1533983400"
},
{
"name": "Superman",
"secret_identity": "Clark Kent",
"timestamp": "1533982500"
},
{
"name": "Wonder Woman",
"secret_identity": "Diana Prince",
"timestamp": "1533981600"
},
{
"name": "Flash",
"secret_identity": "Wally West",
"timestamp": "1533897000"
},
{
"name": "Green Lantern",
"secret_identity": "Hal Jordan",
"timestamp": "1533896100"
},
{
"name": "Cyborg",
"secret_identity": "Victor Stone",
"timestamp": "1533895800"
},
{
"name": "Aquaman",
"secret_identity": "Arthur Curry",
"timestamp": "1533810600"
}
];
}
})(document);
body {
font: normal 12px/15px verdana, arial;
margin: 3em;
}
heroe {
color: red;
font-style: italic;
}
<pre id="raw"></pre>
<h3>**Reduced to output</h3>
<div id="result"></div>
You can group data with reduce function for example, also you can format date object by yourself or if you need some complex formatting in future you can use moment.js library(render "today", "yesterday", "th", "rd" etc). So I don't map month names and used just UTC in my example:
let data = [{
"name": "Batman",
"secret_identity": "Bruce Wayne",
"timestamp": "1533983400" // Epoch timestamp equating to 11th August 2018 at 10:30am
},
{
"name": "Superman",
"secret_identity": "Clark Kent",
"timestamp": "1533982500" // Epoch timestamp equating to 11th August 2018 at 10:15am
},
{
"name": "Wonder Woman",
"secret_identity": "Diana Prince",
"timestamp": "1533981600" // Epoch timestamp equating to 11th August 2018 at 10:00am
},
{
"name": "Flash",
"secret_identity": "Wally West",
"timestamp": "1533897000" // Epoch timestamp equating to 10th August 2018 at 10:30am
},
{
"name": "Green Lantern",
"secret_identity": "Hal Jordan",
"timestamp": "1533896100" // Epoch timestamp equating to 10th August 2018 at 10:15am
},
{
"name": "Cyborg",
"secret_identity": "Victor Stone",
"timestamp": "1533895800" // Epoch timestamp equating to 10th August 2018 at 10:00am
},
{
"name": "Aquaman",
"secret_identity": "Arthur Curry",
"timestamp": "1533810600" // Epoch timestamp equating to 9th August 2018 at 10:30am
}]
let result = data.reduce((acc, item) => {
let date = new Date(item.timestamp*1000);
let key = `${date.getUTCDate()}-${date.getUTCMonth()+1}-${date.getUTCFullYear()}`;
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(item);
return acc;
}, {})
console.log(result)
There are two smaller problems that you are trying to solve here:
Mapping epoch to date,
Grouping events by date
I'll use utility libraryramda to simplify the answer, but you could implement your own groupBy function if you wanted to.
Possible solution:
const epochToDate = epoch => {
const date = new Date(epoch)
return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`
}
const groupedJson = R.groupBy(
event => epochToDate(parseInt(event.timestamp, 10)),
rawJson
)
You can play with it in ramda repl.
u have to import the json file to your react application like this
import data from './data.json'
this.data = data
and just work with it like any other object
outJSON= [ {team: "TeamA",name: "Ahmed",field3:"val3"}, {team: "TeamB",name: "Ahmed",field3:"val43"}, {team: "TeamA",name: "Ahmed",field3:"val55"} ]
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
var groubedByTeam=groupBy(outJSON, 'team')
console.log(groubedByTeam);

Categories