Noah
Noah

Reputation: 38

Sum of values in javascript object

I have the following javascript object

const reizen = {
personen: [
    {
        naam: "Bob",
        reizen: [
            {
                locatie: "Frankrijk",
                uitgaven: [
                    { voorwerp: "Sokken", prijs: 15 },
                    { voorwerp: "Sleutelhanger", prijs: 6 },
                    { voorwerp: "Restaurant", prijs: 26 },
                ]
            },

            {
                locatie: "Duitsland",
                uitgaven: [
                    { voorwerp: "Taxi", prijs: 30 },
                ]
            }
        ]
    },
]
}

I'm trying to get the sum of all values where it says 'prijs' (it's in dutch) Is there an 'easy' way to do this?

EDIT: Thanks everyone for the amazing replies! I got it to work thanks to you guys.

Upvotes: 1

Views: 92

Answers (5)

Ben Stephens
Ben Stephens

Reputation: 3371

If you need to cope with prijs appearing in places which aren't well defined you could do something like the following using recursion:

const reizen = {"personen":[{"naam":"Bob","reizen":[{"locatie":"Frankrijk","uitgaven":[{"voorwerp":"Sokken","prijs":15},{"voorwerp":"Sleutelhanger","prijs":6},{"voorwerp":"Restaurant","prijs":26}]},{"locatie":"Duitsland","uitgaven":[{"voorwerp":"Taxi","prijs":30}]}]}]};

const random = {
  one: { prijs: 6 },
  two: [
    { prijs: 12, other: [{ prijs: 7 }, { prijs: 3 }] },
    { prijs: 2, something: 'fred' },
  ],
};

const sum_prijs = (source) =>
  Array.isArray(source) ?
    source.map(sum_prijs).reduce((a, b) => a + b) :
    Object.entries(source).reduce(
      (acc, [key, val]) =>
        acc + ((typeof val === 'object') ? sum_prijs(val) : (key === 'prijs' ? val : 0)),
      0
    );

console.log(sum_prijs(reizen));
console.log(sum_prijs(random));

Basically the same thing but without recursion:

const reizen = {"personen":[{"naam":"Bob","reizen":[{"locatie":"Frankrijk","uitgaven":[{"voorwerp":"Sokken","prijs":15},{"voorwerp":"Sleutelhanger","prijs":6},{"voorwerp":"Restaurant","prijs":26}]},{"locatie":"Duitsland","uitgaven":[{"voorwerp":"Taxi","prijs":30}]}]}]};

const random = {
  one: { prijs: 6 },
  two: [
    { prijs: 12, other: [{ prijs: 7 }, { prijs: 3 }] },
    { prijs: 2, something: 'fred' },
  ],
};

const push_concat = (array1, array2) => {
  for(let i = 0; i < array2.length; i++)
    array1.push(array2[i]);

  return array1;
};

const sum_prijs = (source) => {
  let sum = 0;
  let queue = [source];
  
  while(queue.length > 0) {
    let item = queue.pop();
    
    if(Array.isArray(item))
      push_concat(queue, item);
    else
      Object.entries(item).forEach(([key, val]) => {
        if(typeof val === 'object')
          queue.push(val);
        else if(key === 'prijs')
          sum += val;
      });
  }
  
  return sum;
};

console.log(sum_prijs(reizen));
console.log(sum_prijs(random));

Upvotes: 0

gavgrif
gavgrif

Reputation: 15499

Its not totally sexy - and I would not actually do this - but to give an alternative to the maps / reduces etc, especially if the object structure is variable or unknown - the simplest way to get the total count without recursion is to stringify the object (JSON.stringify), split on the "prijs' to give an array of strings that start with the target numbers and then (ignoring the first item which does not contain any targert values), parseFloat the strings (which will parse the integer characters until the first non integer character) to get the numbers and add.

const reizen = {
personen: [
    {
        naam: "Bob",
        reizen: [
            {
                locatie: "Frankrijk",
                uitgaven: [
                    { voorwerp: "Sokken", prijs: 15 },
                    { voorwerp: "Sleutelhanger", prijs: 6 },
                    { voorwerp: "Restaurant", prijs: 26 },
                ]
            },

            {
                locatie: "Duitsland",
                uitgaven: [
                    { voorwerp: "Taxi", prijs: 30 },
                ]
            }
        ]
    },
]
}

const stringifiedObj = JSON.stringify(reizen);
const portions = stringifiedObj.split('prijs\":');

let count = 0;
for(let i = 1; i < portions.length; i++) {
 count += parseFloat(portions[i])
 }
 
 console.log(count) // gives 77  (15 + 6 + 26 + 30)

Upvotes: 1

Hans Murangaza DRCongo
Hans Murangaza DRCongo

Reputation: 860

at the level of reizen (second one)

function getTotalPrijs(reizen_){
   // var reizen_ = reizen.personen[0].reizen;
    let _prijs = 0
    reizen_.map((item, index)=>{
        const uitgaven = item.uitgaven;
        uitgaven.map(itm => typeof itm.prijs === "number"? _prijs+=itm.prijs : null)
    })
    return _prijs
}

at the level of personen (first one)

var total_prijs = 0
reizen.personen.map(item =>{
    const reizen = item.reizen;
    total_prijs+=(getTotalPrijs(reizen))
    
})

console.log(total_prijs)

Upvotes: 0

Peterrabbit
Peterrabbit

Reputation: 2247

Assuming your arrays could contain more that one item, you could use nested reducers:

const reizen = {
  personen: [{
    naam: "Bob",
    reizen: [{
        locatie: "Frankrijk",
        uitgaven: [{
            voorwerp: "Sokken",
            prijs: 15
          },
          {
            voorwerp: "Sleutelhanger",
            prijs: 6
          },
          {
            voorwerp: "Restaurant",
            prijs: 26
          },
        ]
      },

      {
        locatie: "Duitsland",
        uitgaven: [{
          voorwerp: "Taxi",
          prijs: 30
        }, ]
      }
    ]
  }, ]
}
const result = reizen.personen.reduce((tot, per) =>
  tot + per.reizen.reduce((acc, item) =>
    acc + item.uitgaven.reduce((res, it) => res + it.prijs, 0), 0), 0);
console.log(result);

Upvotes: 0

Hritik Sharma
Hritik Sharma

Reputation: 2010

const reizen = {
personen: [
    {
        naam: "Bob",
        reizen: [
            {
                locatie: "Frankrijk",
                uitgaven: [
                    { voorwerp: "Sokken", prijs: 15 },
                    { voorwerp: "Sleutelhanger", prijs: 6 },
                    { voorwerp: "Restaurant", prijs: 26 },
                ]
            },

            {
                locatie: "Duitsland",
                uitgaven: [
                    { voorwerp: "Taxi", prijs: 30 },
                ]
            }
        ]
    },
]
}

let arr = reizen.personen ;
let sum = 0;
arr.map(temp=>{
  temp.reizen.map(val=>
  val.uitgaven.map(obj=>{  if(obj.prijs)sum+=obj.prijs})
)})

console.log(sum)

Upvotes: 0

Related Questions