3

I have an array of objects:

var array = [{
    id: "cards",
    amount: 5
}, {
    id: "shirts",
    amount: 3
}, {
    id: "cards",
    amount: 2
}, {
    id: "shirts",
    amount: 3
}]

What I need to do is loop through this array and find the total of all id types. So in this example, I would find the total amount of cards and shirts.

I'm not sure how to do this with objects. I've tried stripping the objects down with Object.values(array), but is there a way to do it with the objects?

Thanks for your help.

12 Answers 12

1

This should do what you want:

var array = [
  { id: "cards", amount: 5 }, 
  { id: "shirts", amount: 3 },
  { id: "cards", amount: 2 }, 
  { id: "shirts", amount: 3 }
];

var result = array.reduce(function(entities, item) {
       entities[item.id] = (entities[item.id] || 0) + item.amount;
       return entities;
}, {})


console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

1

You would loop your array, check the id property for your target object, then enumerate and outer scope variable with the value stored in the amount property.

var totalShirts = 0;
var totalCards = 0;
for(var i = 0, len = array.length; i < len; i++){
    var entry = array[i];
    if(entry.id === "cards"){
        totalCards += entry.amount;
    }
    else if(entry.id === "shirts"){
        totalShirts += entry.amount;
    }
}
console.log("Total Cards: " + totalCards);
console.log("Total Shirts: " + totalShirts);

Comments

1

Here is an example that gets the total of each item

var array = [{id:"cards", amount: 5}, {id:"shirts", amount: 3}, {id:"cards", amount: 2}, {id:"shirts", amount: 3}];

var result = array.reduce(function(accumulator, current) {
  if (!(current.id in accumulator)) {
    accumulator[current.id] = current.amount;
  } else {
    accumulator[current.id] += current.amount;
  }
  
  return accumulator;
}, {});

console.log(result);

Comments

1

A simple forEach will do the trick:

var counts = {}
array.forEach(v => {
  counts[v.id] = (counts[v.id] || 0) + v.amount
})
console.log(counts)

will print:

{
    cards: 7
    shirts: 6
}

4 Comments

Is return statement necessary?
@guest271314 - I assume so because the return will add the new count to the counts object...?
@HappyGreybush return statement can be omitted. counts[v.id] = (counts[v.id] || 0) + v.amount assigns the value.
Indeed, return is not necessary, I had a solution using .map that I changed for a forEach and forgot about that :) Edited
0

Here is a O(n) time solution.

var totals = new Object();

for(var i = 0;i < array.length;i ++) {
  var id = array[i].id;
  var amount = array[i].amount;
  if(totals[id] == undefined) {
    totals[id] = amount; 
  } else {
    totals[id] += amount;
  }
}
console.log(totals);

Comments

0

You can use for..of loop

var array = [{
  id: "cards",
  amount: 5
}, {
  id: "shirts",
  amount: 3
}, {
  id: "cards",
  amount: 2
}, {
  id: "shirts",
  amount: 3
}]

let res = {};

for (let {id,amount} of array) {
  if (!res.hasOwnProperty(id)) res[id] = 0;
  res[id] += amount;
}

console.log(res);

Comments

0

Use a for-loop to do this:

var totalCards = 0; 
var totalShirt = 0;
for (var i = 0; i < arr.length; i++) {
    if (arr[i].id === "cards") {
        totalCards += arr[i].amount;
    } else {
        totalShirt += arr[i].amount;
    }
}

Comments

0

Do the magic in for loop. This example should be general enough:

var array = [ {id:"cards", amount: 5}, {id:"shirts", amount: 3}, {id:"cards", amount: 2}, {id:"shirts", amount: 3} ];
var output = [];
    
for(var i of array) {
  if(!output[i.id]) {
    output[i.id] = 0;
  }
  output[i.id] += i.amount;
}
    
console.log(output);

Comments

0

var array = [{id:"cards", amount: 5}, {id:"shirts", amount: 3}, {id:"cards", amount: 2}, {id:"shirts", amount: 3}];

var arr = [];
array.forEach(v => arr.push(v.id));
var newArr = [...new Set(arr)];
var arr2 = [];

newArr.forEach(function(v) {
  var obj = {};
  obj.id = v;
  obj.counter = 0;
  arr2.push(obj);
});

arr2.forEach(v => array.forEach(c => c.id == v.id ? v.counter += c.amount : v));
console.log(arr2);

Comments

0

You can use Array.forEach() to iterate over each element of the array. The total object is an associative array where the index is the id field of array element objects.

var array = [{ id: "cards", amount: 5 },
             { id: "shirts", amount: 3 },
             { id: "cards", amount: 2},
             { id: "shirts", amount: 3 }];
var total = {};
array.forEach(function (el) {
  if (total[el.id]) {
    total[el.id] += el.amount
  } else {
    total[el.id] = el.amount
  }
});
console.log(JSON.stringify(total));

Comments

0

You could use Array#reduce and sum the amount.

var array = [{ id: "cards", amount: 5 }, { id: "shirts", amount: 3 }, { id: "cards", amount: 2 }, { id: "shirts", amount: 3 }],
    result = array.reduce(function (r, a) {
        r[a.id] = (r[a.id] || 0) + a.amount;
        return r;
    }, {});
    
console.log(result);

3 Comments

I'm afraid that he wants total amount of each types, not just total amount of everything.
@Kinduser, i was thinking i was missing something.
@Kinduser i am so delighted ;-)
-1

You can use this code

if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

then you can do this in older browsers as well:

var len = Object.keys(obj).length;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.