0

I have the following array:

var array = []
array.push({payslipId: 1759});
array.push({payDate: "2019-04-19T00:00:00+00:00"});
array.push({periodsPerYear: 52});
array.push({taxPeriod: 2});
array.push({payslipId: 1760});
array.push({payDate: "2019-04-19T00:00:00+00:00"});
array.push({periodsPerYear: 52});
array.push({taxPeriod: 2});

What I am hoping to be able to do is create an array of distinct names, and where the values are numeric, the total off all in the above array would be shown.

The only way I can think to do this is to create a new array, and add each name to it, then loop around the above array, and add to the value to the name, if the value is numeric.

I am not overly familiar with javascript, so am hoping there is a neater way, a bit like linq in C#?

Desired output:

[{ payslipId: 3519 }, { periodsPerYear: 104} , { taxPeriod: 4}]

8
  • Possible duplicate of Group by in Javascript using reduce Commented Aug 29, 2019 at 18:12
  • The array has four different key-value pairs: payslipId, payDate, 'periodsPerYear` and taxPeriod. When you say you want to add up numeric values do you mean all fields except payDate? Why do wan to add payslipId with period related fields? Commented Aug 29, 2019 at 18:13
  • 1
    Can you show how your desired output looks like ? IMO you're looking for Object Commented Aug 29, 2019 at 18:14
  • Added the desired output to the question. Commented Aug 29, 2019 at 18:17
  • @PM77-1 hmm, I ideally don't want to have to tell a function what the fields are, I'd like to group it, as the array can be different, and I want a generic function. Commented Aug 29, 2019 at 18:27

3 Answers 3

1

You could take a Map and reduce the array by taking the only key/value pair of the object.

function group(array) {
    return Array.from(
        array.reduce((m, o) => {
            var [k, v] = Object.entries(o)[0];
            return typeof v === 'number'
                ? m.set(k, (m.get(k) || 0) + v)
                : m;
        }, new Map),
        ([k, v]) => ({ [k]: v })
    );
}

var array = [{ payslipId: 1759 }, { payDate: "2019-04-19T00:00:00+00:00" }, { periodsPerYear: 52 }, { taxPeriod: 2 }, { payslipId: 1760 }, { payDate: "2019-04-19T00:00:00+00:00" }, { periodsPerYear: 52 }, { taxPeriod: 2 }],
    result = group(array);

console.log(result);

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

Comments

1

As I have mentioned in the comment to the original post, you can use reduce() function for aggregation. You may apply any condition you need to for aggregation. As you have mentioned, I have considered number fields only.

Here you go:

var array = []
array.push({ payslipId: 1759 });
array.push({ payDate: "2019-04-19T00:00:00+00:00" });
array.push({ periodsPerYear: 52 });
array.push({ taxPeriod: 2 });
array.push({ payslipId: 1760 });
array.push({ payDate: "2019-04-19T00:00:00+00:00" });
array.push({ periodsPerYear: 52 });
array.push({ taxPeriod: 2 });

//console.log(array);
result = array.reduce((aggr, item) => {
    itemKey = Object.keys(item)[0];
    if (Number.isInteger(item[itemKey])) {
        if (!aggr[itemKey]) {
            aggr[itemKey] = 0;
        }
        aggr[itemKey] = parseInt(aggr[itemKey]) + parseInt(item[itemKey]);
    }
    return aggr;
}, {});
console.log(result);

Comments

0

Another option could be:

let array2 = [array[0]];
array.shift();

array.forEach(obj => {
  if(typeof(obj[Object.keys(obj)[0]]) !== 'number')  return;
  //test if the object with the same property name already exists to array2 or not. If it doesn't exist, it will be added to array2. If it does only the value will be added to the existing element
  let test = array2.reduce((accum,obj2) => {
    return accum && (Object.keys(obj2)[0] !== Object.keys(obj)[0]);
  }, true);
  if(test)     array2.push(obj);
  else  array2.find(obj2 => obj2.hasOwnProperty(Object.keys(obj)[0]))[Object.keys(obj)[0]] += obj[Object.keys(obj)[0]];
});

console.log(array2);

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.