0

Can you help point out what is wrong with my code here: The goal is to to compute the total amount spent by a diner party of 3 people, each ordering 2 dishes.

I know there are other ways to do this using 'this' and 'new' in a more oop manner, but I think my approach here is more readable..if I can make it work. The code works fine if each patron only orders 1 dish so there is something wrong with the way I have been trying to access the JS dictionary.

Sorry about the newbie question. Any help is appreciate!

var diners=[
 {name:'adam', entree1:'ramen', price1:11.5, entree2: 'miso', price2 : 3},

 {name:'bobby', entree1: 'udon', price1 :10.69, entree2: 'gyoza', price2 :4.5},

{name:'carly', entree1: 'teriyaki chicken', price1:12, entree2: 'miso', price2 : 3},
];

  var entrees1_total=0;
  for (var d in diners){


 entrees1_total +=  diners[d].price1; //total expense of entree1 for all diners  

 diners[d].tax1 = diners[d].price1*0.082; // method for sales tax

 entrees1_total += diners[d].tax1; //total entree1 price including sales tax
 }

 var entrees2_total=0;
 for (var d in diners){


entrees2_total += diners[d].price2;

diners[d].tax2 = diners[d] * price2 * 0.082;

entrees2_total += diners[d].tax2;
}

 var total = entree1_total + entree2_total;

 var total_bill = total*1.2;   //tips

 console.log("total is: " + total_bill.toString());

 for (var d in diners) {
 console.log(diners[d].name + " spends " + (diners[d].price1 + diners[d].tax1)+(diners[d].price2 + diners[d].tax2));
    }   // print out total spent for each patron
Jongware
  • 22,200
  • 8
  • 54
  • 100
iamthewalrus
  • 77
  • 1
  • 7

4 Answers4

1

You can just use .reduce() to iterate the array and keep a running total:

var rawTotal = diners.reduce(function(cum, obj) {
   return cum + obj.price1 + obj.price2;
}, 0);

// add in tax and tip
var tax = rawTotal * 0.082;
var tip = rawTotal * 0.2;    // assumes you don't include taxes in tip calculation
var finalTotal = rawTotal + tax + tip;

Working demo: https://jsfiddle.net/jfriend00/ure3r2jg/


A few notes about your code:

  1. You should never use for/in to iterate an array. for/in iterates all properties of the object which includes array elements, but can also include other enumerable properties (if any have been added to the object). Instead, use .forEach(), .map(), .reduce() or a regular for (var i = 0; i < array.length; i++) loop or in ES6, for/of.

  2. Your sales tax calculation is not correct. You are multiplying each sub-total value which means the early values get multiplied by the sales tax value multiple times. It is simplest to just accumulate the regular total and then apply the sales tax at the end. Or, multiple the sales tax only by each new price, not by the accumulated total.

  3. You have to decide if tip is calculated before or after taxes. This is matter of preference, but I've shown it where tip is calculated before taxes.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I love your solution! Not only did you point out the mistake in my code but you also offered a much better, FP style solution with the reduce. Also thanks for the advice on avoiding the for/in loop. – iamthewalrus Aug 16 '16 at 06:49
0

This statement looks incorrect

diners[d].tax2 = diners[d] * price2 * 0.082;

I guess you meant "diners[d].price2"

anups
  • 583
  • 1
  • 7
  • 18
0

First off - your diners variable is not a dictionary but an array of anonymous objects. Therefore you can not index the array by objects diners[1] but only by the ordinal number of the objetc in array. For that you use for cycle. Also you had other typos in your code. Find fixed and working code below:

var diners=[
 {name:'adam', entree1:'ramen', price1:11.5, entree2: 'miso', price2 : 3},

 {name:'bobby', entree1: 'udon', price1 :10.69, entree2: 'gyoza', price2 :4.5},

{name:'carly', entree1: 'teriyaki chicken', price1:12, entree2: 'miso', price2 : 3},
];

  var entrees1_total=0;
  for (d=0; d < diners.length; d++){


 entrees1_total +=  diners[d].price1; //total expense of entree1 for all diners  

 diners[d].tax1 = diners[d].price1 * 0.082; // method for sales tax

 entrees1_total += diners[d].tax1; //total entree1 price including sales tax
 }

 var entrees2_total=0;
 for (d=0; d < diners.length; d++){


entrees2_total += diners[d].price2;

diners[d].tax2 = diners[d].price2 * 0.082;

entrees2_total += diners[d].tax2;
}

 var total = entrees1_total + entrees2_total;

 var total_bill = total*1.2;   //tips

 console.log("total is: " + total_bill.toString());

 for (var d in diners) {
 console.log(diners[d].name + " spends " + (diners[d].price1 + diners[d].tax1)+(diners[d].price2 + diners[d].tax2));
    }   // print out total spent for each patron
0

You made few mistakes in second loop and you result in console.log worked like string. Not a number. So the working code is

var diners=[
 {name:'adam', entree1:'ramen', price1:11.5, entree2: 'miso', price2 : 3},

 {name:'bobby', entree1: 'udon', price1 :10.69, entree2: 'gyoza', price2 :4.5},

{name:'carly', entree1: 'teriyaki chicken', price1:12, entree2: 'miso', price2 : 3},
];

  var entrees1_total=0;
  for (var d in diners){


 entrees1_total +=  +diners[d].price1; //total expense of entree1 for all diners

 diners[d].tax1 = diners[d].price1*0.082; // method for sales tax

 entrees1_total += +diners[d].tax1; //total entree1 price including sales tax
 }

 var entrees2_total=0;
 for (var d in diners){


entrees2_total += +diners[d].price2;

diners[d].tax2 = diners[d].price2 * 0.082;

entrees2_total += +diners[d].tax2;
}

 var total = entrees1_total + entrees2_total;

 var total_bill = total*1.2;   //tips

 console.log("total is: " + total_bill.toString());

 for (var d in diners) {
 console.log(diners[d].name + " spends " + (diners[d].price1 +diners[d].tax1 +    diners[d].price2 + diners[d].tax2));
 }

:

Nataliya U
  • 141
  • 2
  • 6
  • you are right. not sure how I managed to screw up typing the second for loop, considering that I was copying and pasting the first one haha. It was a long day. – iamthewalrus Aug 16 '16 at 07:11