2017-08-15 8 views
0

Ich habe ein Array:Berechnung vierteljährliche und jährliche Durchschnitts durch Javascript

const test = [1,2,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; 

ich gruppieren möchten die Elemente des Arrays in Stücke der Größe 3 (Viertel) und die Größe 12 (Jahre):

const quarters = [[1,2,2],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18],[19,20]]; 
const years = [[1,2,2,4,5,6,7,8,9,10,11,12],[13,14,15,16,17,18,19,20]]; 

ich möchte auch die Summe der einzelnen Brocken berechnen:

const quarterSums = [5,15,24,33,42,51,39]; 
const yearSums = [77,132]; 

Wie kann ich das tun?

+0

fügen Sie bitte das gewünschte Ergebnis und was Sie versucht haben. –

+0

Der Ausgang sollte wie folgt aussehen: Viertel: [5,15,24,43]: Summe aus jeweils 3 Elementen Jahre: [77,222] Summe aus jeweils 12 Elementen –

Antwort

1

Wenn Sie gruppieren Elemente in Stücke der Größe wollen n dann:

const groupInto = (n, xs) => xs.reduce((xss, x, i) => { 
 
    if (i % n === 0) xss.push([]); // create a new group 
 
    xss[xss.length - 1].push(x); // push in last group 
 
    return xss; 
 
}, []); 
 

 
const xs = [1,2,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; 
 

 
const quarters = groupInto(3, xs); 
 
const years = groupInto(12, xs); 
 

 
console.log(JSON.stringify(quarters)); 
 
console.log(JSON.stringify(years));

Auf der anderen Seite, wenn Sie wollen, dass die finden Summe dieser Stücke:

const sumInto = (n, xs) => xs.reduce((ys, x, i) => { 
 
    if (i % n === 0) ys.push(0); 
 
    ys[ys.length - 1] += x; 
 
    return ys; 
 
}, []); 
 

 
const xs = [1,2,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; 
 

 
const quarters = sumInto(3, xs); 
 
const years = sumInto(12, xs); 
 

 
console.log(JSON.stringify(quarters)); 
 
console.log(JSON.stringify(years));

Hoffnung, das hilft.

+0

Das wollte ich. –

2

Verwenden Sie eine Schleife, die um die Gruppengröße erhöht wird, und verwenden Sie .slice().

EDIT: Sie hinzugefügt Informationen nicht in der ursprünglichen Frage. Da Sie die Summe jedes Quartals/Jahres scheinen möchten, fügen Sie diese .reduce((s,n)=>s+n, 0) zu jeder Teilmenge hinzu. Dies zeigt eine bessere Verwendung von .reduce().

const test = [1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; 
 

 
console.log(getGroups(test, 3)); // quarters 
 
console.log(getGroups(test, 12)); // years 
 

 
function getGroups(a, s) { 
 
    for (var i = 0, r = []; i < a.length; i += s) { 
 
    r.push(a.slice(i, i + s).reduce((s,n)=>s + n, 0)); 
 
    } 
 
    return r; 
 
}

so etwas wie .reduce() verwenden, die jedes Element macht es komplizierter in diesem Fall besucht. Die traditionelle for-Schleife bietet den Vorteil, zu definieren, wie die Schleife inkrementiert werden soll.


Wenn Sie eine Funktion Art und Weise bevorzugen, würde ich immer noch verwenden, nicht .reduce(), würde aber meinen eigenen Schwanz Rekursion rollen.

const test = [1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; 
 

 
console.log(getGroups(test, 3)); // quarters 
 
console.log(getGroups(test, 12)); // years 
 

 
function getGroups(a, s) { 
 
    return function p(a, s, r) { 
 
    return !a.length ? r : r.concat(a.slice(0, s).reduce((s,n)=>s + n, 0), 
 
            p(a.slice(s), s, r)); 
 
    }(a, s, []); 
 
}

+1

Mit 'reduce' wird es nicht komplizierter. Hören Sie auf, Fehlinformationen zu verbreiten. –

+1

@AaditMShah: Wenn Sie ein Konstrukt verwenden, das jedes Element in einem Fall besucht, in dem Sie nur eine Teilmenge besuchen müssen, kommt eine Komplikation hinzu. Sie müssen zusätzlichen Code schreiben, der bestimmt, ob Sie am Anfang einer Untergruppe oder in der Mitte stehen. – spanky

+0

'0' Anfangswert in Ihrem' reduce' Ausdruck ist nicht notwendig –

1

Sie könnten ein Array#forEach mit einem Objekt als temporärer Variable verwenden, um die Werte für das Sammeln. Dann berechne den Durchschnitt.

var values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], 
 
    temp = { quarter: { avg: [], items: 3, sum: 0 }, year: { avg: [], items: 12, sum: 0 } } 
 
    
 
values.forEach(function (v, i) { 
 
    Object.keys(temp).forEach(function (k) { 
 
     temp[k].sum += v; 
 
     if (i && (i + 1) % temp[k].items === 0) { 
 
      temp[k].avg.push(temp[k].sum/temp[k].items); 
 
      temp[k].sum = 0; 
 
     } 
 
    }); 
 
}); 
 

 
console.log(temp.quarter.avg); 
 
console.log(temp.year.avg);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Verwandte Themen