Reduce with Sort

Asked

Viewed 62 times

-1

I need to reduce a array, adding the values (I was able to do the code below), now with this reduction I need to do a kind of a SORT to then catch the 3 biggest and the others I’ll make like an if for others I don’t know if you have one lib in nodejs that would facilitate.

  1. REDUCE
  2. SORT BY THE THREE LARGEST

       var array=[ {
    
            "paymentId" : 1,
            "value" : 290
        },
        {
            "paymentId" : 2,
            "value" : 223
        },
        {
            "paymentId" : 1,
            "value" : 2333
        },
        {
            "paymentId" : 3,
            "value" : 24432
        },
        {
            "paymentId" : 4,
            "value" : 23424
        },
        {
            "paymentId" : 5,
            "value" : 2323
        },
    ]
    var r = array.reduce(function(pv, cv) {
        if ( pv[cv.paymentId] ) {
            pv[cv.paymentId] += cv.value;
        } else {
            pv[cv.paymentId] = cv.value;
        }
        return pv;
    }, {});
    
    console.log(r);
    

EXAMPLE OF 0 RESULT FOR OTHERS

[
    {
        "paymentId" : 3,
        "value" : 24423
    },
    {
        "paymentId" : 4,
        "value" : 23424
    },
    {
        "paymentId" : 1,
        "value" : 2623
    },
    {
        "paymentId" : 0,
        "value" : 2222
    },   
]

1 answer

0

If you’re going to turn the array into an object to be able to access the ids from the index, I recommend storing the entire internal object in those indexes, not just its value, since the end result should keep the same format.

var obj = array.reduce((pv, cv) => {
    if (pv[cv.paymentId]) pv[cv.paymentId].value += cv.value
    else pv[cv.paymentId] = {...cv}
    return pv
}, {})

Now to organize it through the method sort, you need to convert it back to an array, as there is no way to organize a structure where values are associated with a key.

var arrayOrdenado = Object.values(obj).sort((a, b) => b.value - a.value)

And the sum of the other results can be obtained with reduce:

var resto = {
    paymentId: 0,
    value: resultado.slice(3).reduce((acc, r) => acc + r.value, 0)
}

Functioning:

var array = [{"paymentId":1,"value":290},{"paymentId":2,"value":223},{"paymentId":1,"value":2333},{"paymentId":3,"value":24432},{"paymentId":4,"value":23424},{"paymentId":5,"value":2323}]

var obj = array.reduce((pv, cv) => {
    if (pv[cv.paymentId]) pv[cv.paymentId].value += cv.value
    else pv[cv.paymentId] = {...cv}
    return pv
}, {})

var arrayOrdenado = Object.values(obj).sort((a, b) => b.value - a.value)

var resultado = arrayOrdenado.slice(0, 3).concat({
    paymentId: 0,
    value: arrayOrdenado.slice(3).reduce((acc, r) => acc + r.value, 0)
})

console.log(resultado)

  • Great, thank you very much for the friendly reply

  • What better way would you use to find the first 3 and put the rest at the same value as others ? Example 
[ { paymentId: 3, value: 24432 },
 { paymentId: 4, value: 23424 },
 { paymentId: 1, value: 2623 },
 { paymentId: 0, value: 2546 },
 Where 0 would be the sum of the rest(others)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.