Search code examples
javascriptjavascript-objectsfor-in-loop

Splitting a Bill - JavaScript exercise


I'm currently learning JS, and I'm trying to work through a coding exercise. So far, I've managed to piece together the following code using plenty of resources on parts of the code offline and online. I'm pretty close - just can't get the numbers correct in my result.

Some context: Input an object into the function, output a function showing how much each person should pay or receive based on (total bill / people) in object. Each property == person. Result must be rounded down to 2 decimal places.

function splitTheBill(group) {
    var result = {};
    var sum = 0;

    for (var person in group) {
        sum += group[person];
        var avg = sum / (Object.keys(group).length);
        result[person] = Math.floor(-100 * (group[person] - avg))/100;
    }
    return result;
}

splitTheBill({A: 7, B: 3, C: 2});

// console result comes out to be: { A: -4.67, B: 0.33, C: 2 }

// if avg of above object is 4, then answer should be: {A: -3.00, B: 1.00, C: 2.00} 

The exercise itself shouldn't matter for this question. The question is more on why the code is producing incorrect results. I've checked to see if sum and avg return correct values - they do. It's likely the result[person] within the for..in loop causing a problem, and I don't entirely get why.


Solution

  • You can't get the average of a sum that isn't completely added up yet, so your avg variable isn't what you think it is.

    function splitTheBill(group) {
        var result = {};
        var sum = 0;
    
        for (var key in group) {
            sum += group[key];
        }
        
        var avg = sum / (Object.keys(group).length);
        
        for (var person in group) {
            result[person] = Math.floor(-100 * (group[person] - avg))/100;
        }
        return result;
    }
    
    var r = splitTheBill({A: 7, B: 3, C: 2});
    
    console.log(r);

    using two loops, could probably be done more efficiently, but at least it's verbose.
    Also note, numbers can't be 1.00 etc. you'd need strings for that, created with .toFixed(2)