2

I have javascript array object as below. My need is to sum value base on seach id in the array object.

var array = [
{ id: 1, val: 10 }, 
{ id: 2, val: 25 }, 
{ id: 3, val: 20 }, 
{ id: 1, val: 30 }, 
{ id: 1, val: 25 }, 
{ id: 2, val: 10 }, 
{ id: 1, val: 20 }
],

For example sum of value for id 1 is 10 + 30 + 25 + 20 = 85 , It may be something link linq but I'm not sure in javascript. Thanks for all answers.

2
  • Please show expected ouput Commented Mar 7, 2019 at 8:16
  • Eg. I need to sum value at id=1. So output must be 10 + 30 + 25 + 20 = 85 Commented Mar 7, 2019 at 8:19

8 Answers 8

7

You can use a combination of filter and reduce to get the result you want:

sumOfId = (id) => array.filter(i => i.id === id).reduce((a, b) => a + b.val, 0);

Usage:

const sumOf1 = sumOfId(1); //85

Reading material:

Array.prototype.filter

Array.prototype.reduce

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

Comments

2

A way to do it with a traditional for loop

var array = [
  { id: 1, val: 10 }, 
  { id: 2, val: 25 }, 
  { id: 3, val: 20 }, 
  { id: 1, val: 30 }, 
  { id: 1, val: 25 }, 
  { id: 2, val: 10 }, 
  { id: 1, val: 20 }
];

var sums = {};
for (var i = 0; i < array.length; i++) {
  var obj = array[i];
  sums[obj.id] = sums[obj.id] === undefined ? 0 : sums[obj.id];
  sums[obj.id] += parseInt(obj.val);
}

console.log(sums);

running example

1 Comment

Thank you for your kind.
1

You can use reduce() and findIndex()

var array = [
{ id: 1, val: 10 }, 
{ id: 2, val: 25 }, 
{ id: 3, val: 20 }, 
{ id: 1, val: 30 }, 
{ id: 1, val: 25 }, 
{ id: 2, val: 10 }, 
{ id: 1, val: 20 }
];
let res = array.reduce((ac,a) => {
  let ind = ac.findIndex(x => x.id === a.id);
  ind === -1 ? ac.push(a) : ac[ind].val += a.val;
  return ac;
},[])
console.log(res);

1 Comment

Thank you for your kind.
1

JS noob here ... I guess something like this should be here too :-)

let newArray = {}
array.forEach((e) => {
    !newArray[e.id] && (newArray[e.id] = 0);
    newArray[e.id] += e.val;
  });

Comments

0

You can loop on the array and check the ids.

var array = [
  { id: 1, val: 10 }, 
  { id: 2, val: 25 }, 
  { id: 3, val: 20 }, 
  { id: 1, val: 30 }, 
  { id: 1, val: 25 }, 
  { id: 2, val: 10 }, 
  { id: 1, val: 20 }
];

var sum = 0;
var id = 1;

$.each(array, function(index, object){
  if (object.id == id) {
    sum += object.val;
  }
});

console.log(sum);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

1 Comment

Thank you for your kind.
0

Using Array#reduce and Map you can get the sum for each id like so. This also uses destructuring to have quicker access to properties.

const data=[{id:1,val:10},{id:2,val:25},{id:3,val:20},{id:1,val:30},{id:1,val:25},{id:2,val:10},{id:1,val:20}];

const res = data.reduce((a,{id,val})=>{
  return a.set(id, (a.get(id)||0) + val);
}, new Map())

console.log(res.get(1));
console.log(res.get(2));

If you wanted to output all the sums, then you need to use Array#from

const data=[{id:1,val:10},{id:2,val:25},{id:3,val:20},{id:1,val:30},{id:1,val:25},{id:2,val:10},{id:1,val:20}];

const res = Array.from(
  data.reduce((a,{id,val})=>{
    return a.set(id, (a.get(id)||0) + val);
  }, new Map())
);

console.log(res);

If the format should be similar as to your original structure, you need to add a Array#map afterwards to transform it.

const data=[{id:1,val:10},{id:2,val:25},{id:3,val:20},{id:1,val:30},{id:1,val:25},{id:2,val:10},{id:1,val:20}];

const res = Array.from(
  data.reduce((a,{id,val})=>{
    return a.set(id, (a.get(id)||0) + val);
  }, new Map())
).map(([id,sum])=>({id,sum}));

console.log(res);

1 Comment

Thank you for your kind.
0

You could take GroupBy from linq.js with a summing function.

var array = [{ id: 1, val: 10 }, { id: 2, val: 25 }, { id: 3, val: 20 }, { id: 1, val: 30 }, { id: 1, val: 25 }, { id: 2, val: 10 }, { id: 1, val: 20 }],
    result = Enumerable
        .From(array)
        .GroupBy(null, null, "{ id: $.id, sum: $$.Sum('$.val') }", "$.id")
        .ToArray();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>

1 Comment

Thank you for your kind.
0

Here is another option, introducing an Array.prototype.sum helper:

Array.prototype.sum = function (init = 0, fn = obj => obj) {
    if (typeof init === 'function') {
        fn = init;
        init = 0;
    }

    return this.reduce(
        (acc, ...fnArgs) => acc + fn(...fnArgs), 
        init
    );
};

// .sum usage examples
console.log(
    // sum simple values
    [1, 2, 3].sum(),
    // sum simple values with initial value
    [1, 2, 3].sum(10),
    // sum objects
    [{ a: 1 }, { a: 2 }, { a: 3 }].sum(obj => obj.a),
    // sum objects with initial value
    [{ a: 1 }, { a: 2 }, { a: 3 }].sum(10, obj => obj.a),
    // sum custom combinations
    [{ amount: 1, price: 2 }, { amount: 3, price: 4 }]
        .sum(product => product.amount * product.price)
);

var array = [{ id: 1, val: 10 }, { id: 2, val: 25 }, { id: 3, val: 20 }, { id: 1, val: 30 }, { id: 1, val: 25 }, { id: 2, val: 10 }, { id: 1, val: 20 }];

// solutions
console.log(
    array.filter(obj => obj.id === 1).sum(obj => obj.val),
    array.filter(({id}) => id === 1).sum(({val}) => val),
    array.sum(({id, val}) => id === 1 ? val : 0)
);

references:

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.