How to resolve this simple loop in JS?

Hello everyone,

I have JSON data which has array of objects that has timestamp in EPOCH form. Now, I want the number of times a date is repeated(count of same date repeated) so as to generate a graph.

Please do help me.


var obj = [{
    "client_msg_id": "3a223f8d-b5aa-4c9c-9b63-045ec6f90b58",
    "type": "message",
    "text": "hey there",
    "ts": "1567872490.001300",
    "source_team": "TN4AF0V5W",
    "team": "TN4AF0V5W",
    "user_profile": {
      "real_name": "marvelmohinish99",
      "team": "TN4AF0V5W"
    }
  },
  {
    "client_msg_id": "3a223f8d-b5aa-4c9c-9b63-045ec6f90b58",
    "type": "message",
    "text": "welcome",
    "ts": "1567872490.001300",
    "source_team": "TN4AF0V5W",
    "team": "TN4AF0V5W",
    "user_profile": {
      "real_name": "marvelmohinish99",
      "team": "TN4AF0V5W"
    }
  },
  {
    "client_msg_id": "3a223f8d-b5aa-4c9c-9b63-045ec6f90b58",
    "type": "message",
    "text": "Help me",
    "ts": "1567872490.001300",
    "source_team": "TN4AF0V5W",
    "team": "TN4AF0V5W",
    "user_profile": {
      "real_name": "marvelmohinish99",
      "team": "TN4AF0V5W"
    }
  }
];
for(var i=0;i<obj.length;i++){

  var text = obj[i].text;

  var source_team = obj[i].source_team;

  var user_profile = obj[i].user_profile;

  var real_name = user_profile.real_name;

  var ts = obj[i].ts;

  console.log(text);
  console.log(source_team);
  console.log(user_profile);
  console.log(real_name);
  console.log(ts);
}



obj.forEach(function(x, i) {
  setTimeout(function() {
    

    var utc = x.ts;
    var d= new Date(0);
    d.setUTCSeconds(utc);

    var entry = "<div class='name'>" + x.user_profile.real_name + "</div><div class='text'>" + x.text+"</div><div class='ts'>"+ d+"</div>";


    document.getElementById("output").innerHTML += entry;
  }, 2 * i);
});

What is the context of the graph? you just want the number of time a date is repeated in relationship with what?

You can create an empty array where you push the dates and over each loop iteration you can check if the date is in the array with Array.includes(), then save it in a object and add the number of times is matched to a property of that made up object.

Here is the code for that:

let dates = [] , countDates = {};

obj.forEach((el, i)=>{

  if(!dates.includes(el.ts)) {
    dates.push(el.ts);
    countDates[el.client_msg_id] = { id : el.client_msg_id,  count: 1 };
  
  } else if(dates.includes(el.ts))  {
    countDates[el.client_msg_id].count += 1; 
  }
});
 

console.log(countDates);

Pseudo output :

{
  3a223f8d-b5aa-4c9c-9b63-045ec6f90b58: {
     id: "3a223f8d-b5aa-4c9c-9b63-045ec6f90b58",
     count: 3
 },
  id2 : {
    id : String,
    count: Number
  },
  id3 : {
     id : String,
     count: Number
   },
 ......
}

CAn you please explain it in detail?How can I use the object for creating a graph.PLease help me

Since the solution was already given, I will add my two cents and say that it looks that this is a real scenario in a potential real job or serious project.

And because of that I would not shy way of using a library like Lodash or Ramda to do the work for me:

// Assuming the following:
// 1 / import R from { ramda }
// 2 / used a CDN for ramda.min.js

const data = [
  // collapsed list of client objects
];

const getDate = R.compose(
  (ts) => new Date(ts),
  R.multiply(1000),
  R.prop('ts')
)

console.log(
  R.pipe(
    R.map(getDate),
    R.countBy(R.identity)
  )(data)
)

/*
{
  "Sat Sep 07 2019 09:08:10
   GMT-0700 (Pacific Daylight Time)": 3
}
*/

As you can see it will produce an object whose property names are the equivalent of applying JSON.stringify to a Date object and whose values will be the names such date repeats in the array of objects.

Something to rescue from here is that setUTCSeconds is equivalent to multiplying the timestamp by 1000 (because 1 s = 1000 ms).

You can play around with it here:


As for creating the graph, you could rely on a myriad of libraries, starting from the powerful D3.js down to the specialized Chart.js:

https://www.chartjs.org/

The example says that you need an array of labels and an array of values. The labels could be the dates condensed to something as readable as Day/Month/Year and the values would be the times said label repeats. I adjusted my code and added the chart library here:

R.toPairs just returns a list of key value pairs from the produced frequencies object, and R.transponse makes it so I get them separately. But you can implement this using a for-in loop so easily tbh:

const freqObj = {
  "2/5/1998": 6,
  "24/12/2019": 3
}
let labels = []
let freqs = []

for (label in freqObj) {
  labels.push(label)
  freqs.push(freqObj[label])
}

console.log(labels) // ["2/5/1998", "24/12/2019"]
console.log(freqs) // [6, 3]