Javascript time between multiple millisecond dates in an array

If I have an array object once in milliseconds, for example:

  _m7q7sj2wp:
   { '1433891300733': 1433891300733,
     '1433891364133': 1433891364133,
     '1433891526736': 1433891526736,
     '1433891542793': 1433891542793,
     '1433891550861': 1433891550861 },
  _7gh4d0f6l:
   { '1433891352741': 1433891352741,
     '1433891390836': 1433891390836,
     '1433891461772': 1433891461772,
     '1433891523376': 1433891523376,
     '1433891598007': 1433891598007 },

      

It was created with this:

for (var i = 0, j = results.length; i < j; i++){

    var userguid = results[i].guid;

    var timestamp = results[i].ts;
    if(!guid_t[userguid]){

        guid_t[userguid] = {};

    }

    guid_t[userguid][timestamp] = timestamp;
}

      

If there is a better way to create an array, I'm all for it. I don't really like doubling key: value, but I don't know how to do it.

how would i get the time between each element in the array.

For example, items 1-2, 2-3, 3-4, 4-5.

I am trying to get the average time between each item.

The interesting part is that there are about 400 of these arrays, and each of them can have a different number of elements in each.

EDIT: I would say that these are full dates created with+new Date();

Conclusion: I managed to check all three answers, and each of them works! (Don't like just coding?)

In the following tests, approximately 7000-8000 arrays were used. I also had to convert each answer to a function to get through this a lot, but this addition was trivial and took a few seconds. Then I had to add an extra loop for

to combine all the averages into one value.

Also, keep in mind that this is done with nodejs, with data coming from mongodb.

These are not the most detailed benchmarks, but they should give people an overview of the performance I have used with each answer.

Test 1: Originally I chose Saumil Soni's answer because it was the first one I tried. The calculations were performed between 200 and 1200 ms depending on the size of the arrays and the current server load.

Test 2: Then I tried Jack's answer , and even though he was well prepared, I saw almost the same results; sometimes a slight improvement. The calculations were completed from about 175 ms to 1100 ms.

Test 3: Finally, I tried Keith A's answer . I'm not going to lie, I held on because I didn't understand at all reduce

. I did about 10 minutes of reading to find out about it and it turned out to be dead simple. It's just a different way to do a for loop, but uses a different template to execute it.

Here is what I read: Understand Javascript Array in 1 minute

So with shrinking in my pocket, I tried my answer with a little addition to the account so that the mean is not possible because the array only has one value. Performance was slightly better, reaching 75ms to 985ms

Here is the final code I came up with using all 3 answers.

function avg(sum){

    var avg = sum.reduce(function(total, current, index, array){

        if (index < (array.length-1)){
            return total +  (array[index+1] - current);
        }else{
            return total / (array.length-1);
        }
    }, 0);

    if(isNaN(avg)){

        avg = 30000; //Gave it 30 seconds. Making it 0 lowered the over all average by about 20%. Another option would be to discard it, but I needed it. Change to your liking.
    }

    console.log(avg);

}

      

Finally, I changed the accepted answer to Keith A's question because it worked better in my case. But all three answers are absolutely amazing.

+3


source to share


3 answers


you can do it using shortcut

var sum = [1433891352741,
          1433891390836,
          1433891461772,
          1433891523376,
          1433891598007];

var avg = sum.reduce(function(total, current, index, array){
    if (index < (array.length-1)){
        return total +  (array[index+1] - current);
    }else{
        return total / (array.length-1);
    }
}, 0);


alert("Average: "+ avg + " ms or " + avg / 1000 + " sec");

      

http://jsfiddle.net/mp1ofx4r/4/



change your last line to

guid_t[userguid].push(timestamp);

      

so now your guid_t [userguid] contains an array of timestamps instead of objects.

+2


source


Here is a script that will find the time difference between your arrays and then give you the average interval,

<script>

ar = {
    '1433891300733': 1433891300733,
        '1433891364133': 1433891364133,
        '1433891526736': 1433891526736,
        '1433891542793': 1433891542793,
        '1433891550861': 1433891550861
    };
cal(ar);

function cal(ar) {

    var sum = 0;
    var n = Object.keys(ar).length - 1;
    for (var i = 0; i < n; i++) {
        var x = ar[Object.keys(ar)[i]];
        var y = ar[Object.keys(ar)[i + 1]];
        sum += Math.abs(x-y);
    }

    alert("Average: " + sum / n);
}

      



I changed the name of the array for my readability

EDIT: For accessing an object, I changed my loop to access the values โ€‹โ€‹of the objects by their indices.

+2


source


Assuming you have a simple array of values:

var values = [1433891300733, 1433891364133, 1433891526736, 1433891542793, 1433891550861];

// calculate differences between V[k - 1] and V[k]
// for 1 <= k < N
var diffs = [],
prev = values[0];

values.slice(1).forEach(function(value) {
    diffs.push(value - prev);
    prev = value;
});

// calculate average difference
var sum = diffs.reduce(function(total, value) {
    return total + value;
});

if (diffs.length) {
    alert(sum / diffs.length);
}
      

Run codeHide result


If the numbers need to be pulled out of the object, you need a few more steps:

var obj = { '1433891300733': 1433891300733,
     '1433891364133': 1433891364133,
     '1433891526736': 1433891526736,
     '1433891542793': 1433891542793,
     '1433891550861': 1433891550861 };

var values = Object.keys(obj).map(function(key) {
  return obj[key];
}).sort();

console.log(values);
// [1433891300733, 1433891364133, 1433891526736, 1433891542793, 1433891550861]
      

Run codeHide result


+1


source







All Articles