Search code examples
javascriptarraysoopdestructuring

Can i pass a array to constructor of an class by destructuring in javascript


i want to create a class Statistics that'll take 25 inputs or maybe more or less varied number of inputs and does the calculation on it to find mean, median, mode, range, variance, standard deviation etc.

so i was wondering if something like this was possible?

class Solution{

constructor(...inputs){

[this.input1, this.input2, ...rest] = inputs;
}
}

and then in the methods how you work with an array of arguments do i have to use "map" or "forEach" and if i have to then how do you do it? like this?

mean(...inputs){
let sum=0;
inputs.forEach((element)=>{
sum+= element;
})
return sum/inputs.length;
}

my output should look like this:



ages = [31, 26, 34, 37, 27, 26, 32, 32, 26, 27, 27, 24, 32, 33, 27, 25, 26, 38, 37, 31, 34, 24, 33, 29, 26]

console.log('Count:', statistics.count()) // 25

console.log('Sum: ', statistics.sum()) // 744

console.log('Min: ', statistics.min()) // 24

console.log('Max: ', statistics.max()) // 38

console.log('Range: ', statistics.range() // 14

console.log('Mean: ', statistics.mean()) // 30

console.log('Median: ',statistics.median()) // 29

console.log('Mode: ', statistics.mode()) // {'mode': 26, 'count': 5}

console.log('Variance: ',statistics.var()) // 17.5

console.log('Standard Deviation: ', statistics.std()) // 4.2

console.log('Variance: ',statistics.var()) // 17.5

console.log('Frequency Distribution: ',statistics.freqDist()) // [(20.0, 26), (16.0, 27), (12.0, 32), (8.0, 37), (8.0, 34), (8.0, 33), (8.0, 31), (8.0, 24), (4.0, 38), (4.0, 29), (4.0, 25)]

// you output should look like this

console.log(statistics.describe())

Count: 25

Sum:  744

Min:  24

Max:  38

Range:  14

Mean:  30

Median:  29

Mode:  (26, 5)

Variance:  17.5

Standard Deviation:  4.2

Frequency Distribution: [(20.0, 26), (16.0, 27), (12.0, 32), (8.0, 37), (8.0, 34), (8.0, 33), (8.0, 31), (8.0, 24), (4.0, 38), (4.0, 29), (4.0, 25)]

Im still trying to figure out how to pass an variable length of arguments to my class's constructor method


Solution

  • No destructuring is needed; just assign the array to an array property of the instance. Then no parameter is needed for the mean method, since it already has access to that instance property:

    class Solution {
        constructor(inputs) {
            this.inputs = inputs;
        }
        count() {
            return this.inputs.length;
        }
        sum() {
            return this.inputs.reduce((a, b) => a + b, 0);
        }
        _sumSquares() {
            return this.inputs.reduce((a, b) => a + b*b, 0);
        }
        mean() {
            return this.sum() / this.count();
        }
        min() {
            return Math.min(...this.inputs);
        }
        max() {
            return Math.max(...this.inputs);
        }
        range() {
            return this.max() - this.min();
        }
        median() {
            const sorted = this.inputs.toSorted((a, b) => a - b);
            const len = this.count();
            return (sorted[len >> 1] + sorted[(len + 1) >> 1]) / 2;
        }
        _frequencies() {
            const map = new Map(this.inputs.map(value => [value, {value, count: 0}]));
            for (let value of this.inputs) map.get(value).count++;
            return [...map.values()].toSorted((a, b) => b.count - a.count || b.value - a.value);
        }
        mode() {
            const [{value, count}] = this._frequencies();
            return {mode: value, count};
        }
        var() {
            const len = this.count();
            return this._sumSquares() / len - this.mean()**2;
        }
        std() {
            return this.var() ** 0.5;
        }
        freqDist() {
            const coef = 100 / this.count();
            return this._frequencies().map(({value, count}) =>
                [count * coef, value]
            );
        }
        describe() {
            console.log('Count:', this.count()) // 25
            console.log('Sum: ', this.sum()) // 744
            console.log('Min: ', this.min()) // 24
            console.log('Max: ', this.max()) // 38
            console.log('Range: ', this.range()) // 14
            console.log('Mean: ', this.mean()) // 30
            console.log('Median: ', this.median()) // 29
            console.log('Mode: ', this.mode()) // {'mode': 26, 'count': 5}
            console.log('Variance: ', this.var()) // 17.5
            console.log('Standard Deviation: ', this.std()) // 4.2
            console.log('Frequency Distribution: ', this.freqDist()) // [(20.0, 26), (16.0, 27), (12.0, 32), (8.0, 37), (8.0, 34), (8.0, 33), (8.0, 31), (8.0, 24), (4.0, 38), (4.0, 29), (4.0, 25)]
        }
    }
    
    const ages = [31, 26, 34, 37, 27, 26, 32, 32, 26, 27, 27, 24, 32, 33, 27, 25, 26, 38, 37, 31, 34, 24, 33, 29, 26]
    const statistics = new Solution(ages);
    statistics.describe();

    The outputs are not exactly as the code-comments suggest:

    • This snippet does not apply any rounding, you may want to include that where expected
    • The expected output for the frequency distribution is not something that the console would print for an array of arrays, so you may need to convert that array to a string yourself.