Search code examples
javascriptarrayslodash

sum by object key from array but sum only has word provide in function javascript loadsh


i am trying to sum from array by object key but key need to filter by word provided then sum but i don't know how to sum any one can please help me

sum object value only has key.includes('_total') but not key.includes('all_total') and key.includes('cf_total')

let array = [{
        "46": 0,
        "1592_46_1": 3,
        "1592_46_2": 3,
        "1592_46_3": 3,
        "1592_46_1_total": 3,
        "1592_46_1_cf_total": 3,
        "1592_46_2_total": 3,
        "1592_46_2_cf_total": 3,
        "1592_46_3_total": 3,
        "1592_46_3_cf_total": 3,
        "all_total": 3,
        "cf_total": 3,
    },
    {
        "46": 0,
        "1593_46_1": 1,
        "1593_46_2": 1,
        "1593_46_3": 1,
        "1593_46_1_total": 1,
        "1593_46_1_cf_total": 1,
        "1593_46_2_total": 1,
        "1593_46_2_cf_total": 1,
        "1593_46_3_total": 1,
        "1593_46_3_cf_total": 1,
        "all_total": 1,
        "cf_total": 1,

    },
    {
        "46": 0,
        "1594_46_1": 2,
        "1594_46_2": 2,
        "1594_46_3": 2,
        "1594_46_1_total": 2,
        "1594_46_1_cf_total": 2,
        "1594_46_2_total": 2,
        "1594_46_2_cf_total": 2,
        "1594_46_3_total": 2,
        "1594_46_3_cf_total": 2,
        "all_total": 2,
        "cf_total": 2,
    },

];

my function is

let sum = (word) => {
    return _.sumBy(array, function(o)
    {
        return o.n;
    });
};

example sum only value that key include _total word but not include word cf_total and all_total

sum('_total');
return should number 18

Solution

  • You could use reduce for this, and use regex to check whether a number followed by your word is included in each key (to avoid cf_total and all_total):

    // Minified for readability
    const array = [{46:0,"1592_46_1":3,"1592_46_2":3,"1592_46_3":3,"1592_46_1_total":3,"1592_46_1_cf_total":3,"1592_46_2_total":3,"1592_46_2_cf_total":3,"1592_46_3_total":3,"1592_46_3_cf_total":3,all_total:3,cf_total:3},{46:0,"1593_46_1":1,"1593_46_2":1,"1593_46_3":1,"1593_46_1_total":1,"1593_46_1_cf_total":1,"1593_46_2_total":1,"1593_46_2_cf_total":1,"1593_46_3_total":1,"1593_46_3_cf_total":1,all_total:1,cf_total:1},{46:0,"1594_46_1":2,"1594_46_2":2,"1594_46_3":2,"1594_46_1_total":2,"1594_46_1_cf_total":2,"1594_46_2_total":2,"1594_46_2_cf_total":2,"1594_46_3_total":2,"1594_46_3_cf_total":2,all_total:2,cf_total:2}];
    
    const sum = (word, arr) => {
        const regex = new RegExp(`\\d${word}`);
        
        return arr.reduce((total, obj) => {
          return total + Object.entries(obj).reduce((sum, [k, v]) => {
            return sum + (regex.test(k) ? v : 0);
          }, 0);
        }, 0);
    };
    
    const res = sum('_total', array);
    
    console.log(res); // 18