1

I have an array of pokemon objects which have a Max and Min height (see snapshot below) and I need to return the average minimum and maximum height for all pokemon in the form of a tuple

const allPokemon = [
  {
    Height: {
      Minimum: '0.61m',
      Maximum: '0.79m',
    },
  },
];

I need to use HOFs so I was thinking to do something like this for both Maximum and Minimum height:

allPokemon.reduce((acc, cur) => acc + parseInt(cur.Height.Maximum), 0) / allPokemon.length;
allPokemon.reduce((acc, cur) => acc + parseInt(cur.Height.Minimum), 0) / allPokemon.length;

but I'm not sure how to return the two values in the form of a tuple (create empty array and push the values in? Concat method?)

Any help would be much appreciated.

1
  • object would be helpful. Commented Jan 22, 2021 at 9:52

4 Answers 4

3

For now, JavaScript doesn’t have tuples. Besides, Javascript is weakly typed

Weakly typed means the compiler, if applicable, doesn't enforce correct typing. Without implicit compiler interjection, the instruction will error during run-time.

However, with the object or array destructuring you can archive it

  1. You can use .reduce with initial data as object like { Maximum: 0, Minimum: 0 } to aggregate your data like below:

const allPokemon = [
        {
          Height: {
            Minimum: "1.61m",
            Maximum: "2.79m"
           }
        }]
        
var result = allPokemon.reduce((acc, cur) => {
      acc.Maximum += (parseFloat(cur.Height.Maximum)/allPokemon.length);      
      acc.Minimum += (parseFloat(cur.Height.Minimum)/allPokemon.length);
      
      return acc; 
}, { Maximum: 0, Minimum: 0 });

console.log(result);

  1. The second way is using array then destructuring assignment like this

const allPokemon = [
        {
          Height: {
            Minimum: "1.61m",
            Maximum: "2.79m"
           }
        }]
        
var result = allPokemon.reduce((acc, cur) => {
      acc[0] += (parseFloat(cur.Height.Maximum)/allPokemon.length);      
      acc[1] += (parseFloat(cur.Height.Minimum)/allPokemon.length);
      
      return acc; 
}, [0, 0]);

console.log(result);

// Array Destructuring here
const [Maximum, Minimum] = result;
console.log("Maximum: " + Maximum);
console.log("Minimum: " + Minimum);

For example:

const [a, b] = [10, 20]; // a = 10, b= 20

Note: As @VLAZ 's comment, in the near future we'd have proper tuples and records like this one proposal-record-tuple

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

6 Comments

@Phong Mostly yes thank you! How would I implement the allPokemon.length within the code itself rather than in the console.log?
It depends on your logic, you can also move /allPokemon.length into individual calculating like acc.Maximum += (parseFloat(cur.Height.Maximum)/allPokemon.length). But it should move out to calculate average :) @ruggle
I need it to return as an array with the two values i.e. [1,61, 2.79]
ahh, didn't see that one! Thanks for your help! I wasn't aware of the array destructuring technique. I'll need to read upon it!
"No, JavaScript doesn’t have tuples (Because javascript weakly typed)" being weakly typed doesn't have any bearing on having tuples or not. Weakly typed means that conversions can happen. That doesn't mean types don't exist - there are already numbers and strings, among others. A tuple can just be another type and indeed there is a proposal for it. Hopefully in the near future we'd have proper tuples and records (basically named tuples).
|
3

const allPokemon = [
        {
          Height: {
            Minimum: "1.61m",
            Maximum: "2.79m"
           }
        }]
        
const [avgMin, avgMax] = allPokemon.reduce((acc, cur) => {
      acc[0] += parseFloat(cur.Height.Minimum);      
      acc[1] += parseFloat(cur.Height.Maximum);
      
      return acc; 
}, [0, 0]).map(total => total / allPokemon.length)

console.log(`Average min: ${avgMin}\nAverage max: ${avgMax}`);

The first value of the result tuple is the average minimum and the second is the average maximum.

1 Comment

Your updated answer is using destructuring array like me ^^!
1

There's no tuple in JavaScript, you may return an array instead. JS will unpack into variables.

function foo(){
    return ["value1","value2"];
}

[var1,var2] = foo();
console.log(var1,var2);

Comments

0

I don't think you need hof (look at others answers) however if you really want to use hof (e.g as an exercise) you need a function which takes a function as parameter

So e.g

take a function which extracts the numerical property and take a function which uses it to average the data.

function getValue(pokemon) {
  return pokemon.height.Maximum
}

function avgBy(getValue, pokemons) {
  return pokemons.length === 0 ? 0 : pokemons.reduce((s, p) => s + getValue(p), 0) / pokemons.length
}

Then you can indeed compose:

function getMin (pokemon) { return pokemon.height.Minimum }
function getMax (pokemon) { return pokemon.height.Maximum }
const [min, max] = [avgBy(getMin, pokemons), avgBy(getMax, pokemons)]

The nice property is now you have the avgBy which can compute the avg of whatever as long you give it a proper getValue func

function getMin (pokemon) { return pokemon.height.Minimum }
function getMax (pokemon) { return pokemon.height.Maximum }

function avgBy(getValue, pokemons) {
  return pokemons.length === 0 ? 0 : pokemons.reduce((s, p) => s + getValue(p), 0) / pokemons.length
}
const pokemons = [{height:{Maximum: 1, Minimum: 0}}, {height:{Maximum: 3, Minimum:1}}]
const [min, max] = [avgBy(getMin, pokemons), avgBy(getMax, pokemons)]
console.log({min, max})

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.