0

I have an object like so. They key is a timestamp and the value is my number

var history = {
     '1505845390000': 295426,
     '1505757979000': 4115911,
     '1505677767000': 4033384,
     '1505675472000': 4033384,
     '1505591090000': 3943956,
     '1505502071000': 3848963,
     '1505499910000': 3848963,
     '1505499894000': 3848963
}

What I want to do is:

1) For the latest 5 dates (keys), get an average of the values 2) For a date range, get an average of the values

K20GH
  • 6,032
  • 20
  • 78
  • 118

2 Answers2

1

you can do the following for the first case

var obj = {
     '1505845390000': 295426,
     '1505757979000': 4115911,
     '1505677767000': 4033384,
     '1505675472000': 4033384,
     '1505591090000': 3943956,
     '1505502071000': 3848963,
     '1505499910000': 3848963,
     '1505499894000': 3848963
}

let ans = Object.keys(obj).sort();

ans = ans.slice(ans.length-5).reduce((a, b) => a+obj[b], 0);

console.log(ans/5);

For the 2nd case you can do

var obj = {
     '1505845390000': 295426,
     '1505757979000': 4115911,
     '1505677767000': 4033384,
     '1505675472000': 4033384,
     '1505591090000': 3943956,
     '1505502071000': 3848963,
     '1505499910000': 3848963,
     '1505499894000': 3848963
}

let start = '1505591090000', end = '1505845390000'
let ans = Object.keys(obj).filter(e => e>=start && e<=end);

let result = ans.reduce((a,b) => a+obj[b],0)/ans.length

console.log(result);
marvel308
  • 10,288
  • 1
  • 21
  • 32
  • Ahh! I've been trying to convert it to dates and then order them. It never occurred to just sort it first! – K20GH Sep 20 '17 at 19:12
  • How could I adapt the second one to say, filter between start and end, but only where a value is greater than 0. I have an issue where if i have a number of key/values where the value i 0, the average is affected so need to ignore the 0's – K20GH Sep 20 '17 at 22:12
  • Add that condition in the filter – marvel308 Sep 21 '17 at 03:52
  • I dont think thats posssible as you can only access the key and not values? – K20GH Sep 21 '17 at 11:46
  • if you know the key the obj[key] would give you the value – marvel308 Sep 21 '17 at 11:50
  • Oh wow, total brainfart moment. `e>=start && e<=end && obj[e] != 0` thanks! – K20GH Sep 21 '17 at 12:03
0

This answer has a good explanation of how to filter an object by its keys:

https://stackoverflow.com/a/38750895/5009210

Basically use Object.keys() to get an array of keys, then Array.filter() to select the ones you want, then Array.reduce() to reconstruct an object with the relevant values for the filtered keys. Like this:

Object.keys( history )
   .filter( someFilterFunction )
   .reduce( (obj, key) => {
      obj[key] = history[key];
   }, {});

Once you've done this, you can extract the remaining values using Object.values() and then pass them to a simple average function (I assume you want the mean average):

function meanAverage( valuesToAverage ) {
    //avoid divide by zero
    if ( valuesToAverage.length ) {
       const valueSum = sum( valuesToAverage );
       return valueSum / valuesToAverage.length;
    }
    return 0;
}

function sum( valuesToSum ) {
   return valuesToSum.reduce( (a, b) => a + b );
}
Duncan Thacker
  • 5,073
  • 1
  • 10
  • 20