iamthewalrus iamthewalrus -4 years ago 74
Javascript Question

how to properly access a javascript "dictionary" like this one

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

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download