Javascript: How to filter an object array and sum result

11,283

Solution 1

You can do like this if you just want to exclude "c" property but include sum of values of all properties of objects of the array.

var example = [{a:1, b:2, c:3}, {a:4, b:5, c:6}, {a:7, b:8, c:9}];

let sum = 0; 
example.forEach(obj => {
    for (let property in obj) {
        if(property !== "c")
        sum += obj[property];
    }
})

Solution 2

You already have the code to add all properties.
Object.keys(y) get you all properties of the object, the reducer is using them with y[z] assuming z='a' it's like doing y.a: the solution is to filter unwanted properties before the reduce

The change is on this line:

var sumobjects = example.map(y => Object.keys(y).filter(k=>k!=='c').reduce((x,z) => x + y[z], 0));

Here the complete code:

var example = [{a:1, b:2, c:3}, {a:4, b:5, c:6}, {a:7, b:8, c:9}]
var sumobjects = example.map(y => Object.keys(y).filter(k=>k!=='c').reduce((x,z) => x + y[z], 0));
const reducer = (accumulator, currentValue) => accumulator + currentValue;
const sumexample = sumobjects.reduce(reducer)
console.log(sumexample);

If you want to exclude more than one property you can create an array with properties to avoid:
var exceptedProperties = ["c","d"];
The change is

var sumobjects = example.map(y => Object.keys(y).filter(k=>!exceptedProperties.some(p=>p===k)).reduce((x,z) => x + y[z], 0));

Complete code:

var example = [{a:1, b:2, c:3, d:4}, {a:4, b:5, c:6, d:7}, {a:7, b:8, c:9, d:10}]
var sumobjects = example.map(y => Object.keys(y).filter(k=>!exceptedProperties.some(p=>p===k)).reduce((x,z) => x + y[z], 0));
const reducer = (accumulator, currentValue) => accumulator + currentValue;
const sumexample = sumobjects.reduce(reducer)
console.log(sumexample);

Solution 3

You can use the function below and pass the keys to omit as an array of string to the second parameter. The first parameter will be the list itself.

const sumWithout = (list, without) => {
  return list.reduce((acc, item) => {
    for (let [key, value] of Object.entries(item)) {
      if(!without.includes(key)){
        acc = Number(value) + acc;
      }
    }

    return acc;
  }, 0)
}

console.log(sumWithout(yourList, ['c', 'foo', '...' ]));
Share:
11,283
Normajean
Author by

Normajean

Updated on June 05, 2022

Comments

  • Normajean
    Normajean almost 2 years

    I have an object array:

    var example = [{a:1, b:2, c:3}, {a:4, b:5, c:6}, {a:7, b:8, c:9}]
    

    I am trying to add all values that don't correspond with c.

    • I've managed to filter out a row, which wasn't what I was after, with console.log(test.filter(x => x.c > 3));

    • I've also tried a data query and chaining .ne("c") to it, but this didn't work.

    I have managed to find the sum of an object array, but it doesn't omit the elements corresponding with "c". The code for that is:

    var example = [{a:1, b:2, c:3}, {a:4, b:5, c:6}, {a:7, b:8, c:9}]
    var sumobjects
    sumobjects = example.map(y => Object.keys(y).reduce((x,z) => x + y[z], 0));
    const reducer = (accumulator, currentValue) => accumulator + currentValue;
    const sumexample = sumobjects.reduce(reducer)
    console.log(sumexample);
    

    My current code is looking like this:

    var example = [{a:1, b:2, c:3}, {a:4, b:5, c:6}, {a:7, b:8, c:9}]
    function filtration (arr) {
    
     var filteredsum = 0
     for (let i = 0; i < arr.length; i++) {
     for (let j = 0; j < arr[i].length; j++) {
     for(let k = 0; k < arr[i][j].length && arr[i][j] !== "c"; k++)
                filteredsum += arr[i][j]            
            }
        }   
     return(filteredsum);
    }
    console.log(filtration(example));
    

    The answer should be one single number, being 27.

    The code I currently have is outputting 0, so I figure that instead of omitting the property "c" from the sum, it's finding c and then omitting the entire object from the object array.

    EDIT: The object array above is a simplified version of the object array I'm actually working with. The actual object array is not limited to the properties a, b and c. It has about 350 different properties. So code that adds a and b and c by actually stating a, b and c isn't going to be a good option for me.

    • Cuong Le Ngoc
      Cuong Le Ngoc over 4 years
      Your object have just a, b, c property or can have another properties?
    • Normajean
      Normajean over 4 years
      It will have about 350 properties
  • Normajean
    Normajean over 4 years
    Thanks for your answer! I forgot to mention some crucial information in the question. The object array I have in my question is a very simplified version of what I have in reality. My actual object array has about 350 properties. So that return acc = curr.a + curr.b will need to be a mile long. That's why I'm really after some sort of filter or maybe I could create a new array that omits the undesired properties.
  • Normajean
    Normajean over 4 years
    Thanks for your answer. I have added an edit to my question after your answer. I will have about 350 different properties, not just a, b and c. So I'm looking for a way to find their sum without having to state each property.
  • Normajean
    Normajean over 4 years
    Thanks for your answer. I have added an edit to my question after your answer. I will have about 350 different properties, not just a, b and c. So I'm looking for a way to find their sum without having to state each property.
  • JaxonFlexonWaxon
    JaxonFlexonWaxon over 4 years
    @Normajean yes, I have added a different answer as well. Please have a look if that's what you need.
  • Puwka
    Puwka over 4 years
    Have a different answer here. Hope it helps
  • Normajean
    Normajean over 4 years
    This one will also work very well. I will still need the original object array for other calculations. So I have created a copy of var example and I have performed the code you have provided to the copy.
  • JaxonFlexonWaxon
    JaxonFlexonWaxon over 4 years
    @Normajean well the original example array is not affected by the forEach() method. So I do not think you need to create a different copy. Cheers.
  • Normajean
    Normajean over 4 years
    Thank you so much. I'm just learning javascript and have been trying to find the solution to this for about 5 days. Thanks again!
  • JaxonFlexonWaxon
    JaxonFlexonWaxon over 4 years
    Can you please upvote my answer if you found it useful. Thanks :)