Search code examples
javascriptreduce

Reduce to return a specific value while supplying an initial value


Hi I have the following object I am reducing to the key that its value is the greatest:

project.approved_account_ids: {
    "sp02.testnet": 3,
    "sp03.testnet": 1
}

Like so..

<Typography variant="body2">
  Architect: {Object.keys(project.approved_account_ids).reduce((a, b) => project.approved_account_ids[a] > project.approved_account_ids[b] ? a : b)}
</Typography>}

But if the object is like

project.approved_account_ids: {}

I get the error - TypeError: Reduce of empty array with no initial value. Which I know it is because there is not always keys and values to reduce.

I tried adding an initial value at the end like

{Object.keys(project.approved_account_ids).reduce((a, b) => project.approved_account_ids[a] > project.approved_account_ids[b], 0 ? a : b)}

But that doesn't work. What would be the best method to check if there are values in the first place before applying reduce()? Any help would be appreciated!!


Solution

  • Assuming that you just want the highest value, so just the actual number?

    • Used Object.entries() on the object found here: obj.project.approved_account_ids
    Object.entries(obj).reduce(
    // Obj is now an array of pairs: [[key, val], [key, val],...]
    
    • Next set the initial value to a phony pair: ["key",-1] and then compare that initially which of course be replaced on the first iteration:
    (max, [key, val]) =>
        max[1] > val ? max : [key, val], ["key", -1]
    // Note the second param is destructured to a pair [key, val]
    
    • Return the second value of the highest pair: output[1]

    In regards to an empty object or no number values it will not fail it will return -1 instead, see objB in example. Also, Object.values() works as well, but decided on Object.entries() just in case the actual key matters as well.

    const obj = {
      project: {
        approved_account_ids: {
          "sp02.testnet": 3,
          "sp03.testnet": 1,
          "sp00.testnet": null,
          "sp04.testnet": 5,
          "sp05.testnet": 3
        },
        pending_account_ids: {}
      }
    };
    
    const objA = obj.project.approved_account_ids;
    
    const objB = obj.project.pending_account_ids;
    
    
    function maxV(obj) {
      let output = Object.entries(obj).reduce(
        (max, [key, val]) =>
        max[1] > val ? max : [key, val], ["key", -1]
      )
      return output;
    }
    
    console.log('Returning the highest number: maxV(objA)[1]');
    console.log(maxV(objA)[1]);
    
    console.log('Returning from an empty object: maxV(objB)[1]');
    console.log(maxV(objB)[1]);
    
    console.log('Returning the key of the highest number: maxV(objA)[0]');
    console.log(maxV(objA)[0]);
    
    console.log('Returning the key and the highest number as an array: maxV(objA)');
    console.log(maxV(objA));
    
    console.log('Returning the key and the highest number as an object: Object.fromEntries([[...maxV(objA)]])');
    console.log(Object.fromEntries([[...maxV(objA)]]));