1

i have an array like this:

["2011-06-16 16:37:20",23.2],
["2011-06-21 16:37:20",35.6],
["2011-06-26 16:37:20",41.8],
["2011-07-01 16:37:20",25],
["2011-07-06 16:37:20",22.8],
["2011-07-11 16:37:20",36.4],
["2011-07-16 16:37:20",34],
["2011-07-21 16:37:20",20]
[...]

Format: [$date,count]

Now i need to add an 3rd an 4th value to every array element, which is an average of N counts before or after.

Example if N=3

the 3rd value should be the average of the 3 count-values before and the 4th value should be the average of the 3 count-values after the current array element. The Result look like that:

["2011-06-16 16:37:20",23.2, null,  34.13],
["2011-06-21 16:37:20",35.6, null,  29.86],
["2011-06-26 16:37:20",41.8, null,  28.06],
["2011-07-01 16:37:20",25,   33.53, 31.06],
["2011-07-06 16:37:20",22.8, 34.13, 30.13],
["2011-07-11 16:37:20",36.4, 29.86, null],
["2011-07-16 16:37:20",34,   28.06, null],
["2011-07-21 16:37:20",20,   31,06, null]

the null value is nothing more then an placeholder for values which cant be calculated, because there are not enough values to calculate an average of N counts. It's also possible to place the average of all available counts, like "24.4"(23.2+35.6)/2 for the 3rd line instead of null:

["2011-06-26 16:37:20",41.8, 24.4,  28.06],

I have no idea, ho to build code for that.

Hope for an hint or assistance.

Thank you.

//Update: sorry, but..please: could somebody explain me, why 2 people votes this question down? I don't know why. That's not fair - talk to me, if i did an mistake? Sorry for that!

6
  • You should really try to do this yourself and then ask for specific help on something that is giving you trouble. Asking the community to write it for you isn't what this site is all about... Commented Jul 21, 2011 at 15:16
  • Sorry, but i tried this for 3 hours - but no idea. It's not a problem to iterate trough the array, but i don't know how to get n values before and n values after the current. Commented Jul 21, 2011 at 15:18
  • Try to implement a solution where N=1 - that is, just average this number and the one before. Then try N=2 and see if a pattern emerges. Commented Jul 21, 2011 at 15:31
  • @The Bndr: post the code you tried! The best way to learn is to have someone point out the problem with your approach; otherwise, it's just too tempting to use someone else's solution without really understanding it. Commented Jul 21, 2011 at 16:19
  • @The Bndr - The votes to close are because this is not a problem anyone other than you is likely to care about. It's a very specific issue. That said, I'm bored, so I added a solution. Commented Jul 21, 2011 at 17:01

2 Answers 2

2

A solution using various higher-order functions:

var arrs = [
    ["2011-06-16 16:37:20",23.2],
    ["2011-06-21 16:37:20",35.6],
    ["2011-06-26 16:37:20",41.8],
    ["2011-07-01 16:37:20",25],
    ["2011-07-06 16:37:20",22.8],
    ["2011-07-11 16:37:20",36.4],
    ["2011-07-16 16:37:20",34],
    ["2011-07-21 16:37:20",20]];

function avg(arr) {
    return (arr.reduce(function(acc, el, i) {
        return el + acc;
    }, 0) / arr.length).toFixed(2) * 1;
}

function visit(acc, el, i, arr) {
    el.push((acc.length >= 3) ? avg(acc) : null);
    acc[i % 3] = el[1];
    return acc;
}

arrs.reduce(visit, []);
arrs.reverse().reduce(visit, []);
arrs.reverse();

Result:

[["2011-06-16 16:37:20", 23.2, null, 34.13], 
 ["2011-06-21 16:37:20", 35.6, null, 29.87], 
 ["2011-06-26 16:37:20", 41.8, null, 28.07], 
 ["2011-07-01 16:37:20", 25, 33.53, 31.07], 
 ["2011-07-06 16:37:20", 22.8, 34.13, 30.13], 
 ["2011-07-11 16:37:20", 36.4, 29.87, null], 
 ["2011-07-16 16:37:20", 34, 28.07, null], 
 ["2011-07-21 16:37:20", 20, 31.07, null]]
Sign up to request clarification or add additional context in comments.

1 Comment

thank you for that posted solution. It took a few minutes, until I understood what's going on there, how this code works. But now, I understand this code. Iterating the array twice, and the second run reverse, is an practice, i never thought about. Great! Thank you so much.
2
arrays = [
    ["2011-06-16 16:37:20",23.2],
["2011-06-21 16:37:20",35.6],
["2011-06-26 16:37:20",41.8],
["2011-07-01 16:37:20",25],
["2011-07-06 16:37:20",22.8],
["2011-07-11 16:37:20",36.4],
["2011-07-16 16:37:20",34],
["2011-07-21 16:37:20",20]
];
arrays.forEach(function(el,i,theArray){
    var a=null,b=null;
    if(i > 2){
        a = (theArray[i-3][1] + theArray[i-2][1] + theArray[i-1][1]) / 3;
        a = a.toPrecision(a.toString().indexOf('.') != -1 ? 2+a.toString().indexOf('.') : a.toString().length);
    }
    if(i < theArray.length - 3){
        b = (theArray[i+3][1] + theArray[i+2][1] + theArray[i+1][1]) / 3;
        b.toPrecision(b.toString().indexOf('.') != -1 ? 2+b.toString().indexOf('.') : b.toString().length);
    }
    el.push(a);
    el.push(b);
});

1 Comment

Thank you, for your answer and your time, you had spend to that solution. unfortunately, I only can mark one answer as right - so i will take the solution from lwburk, which looks more compact and robust. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.