1

I've fetched data from PokeAPI, and now I'm struggling with creating an object containing this data. Data looks like this:

valueObject = {
  "stats": [{
      "base_stat": 45,
      "effort": 0,
      "stat": {
        "name": "speed",
        "url": "https://pokeapi.co/api/v2/stat/6/"
      }
    },
    {
      "base_stat": 65,
      "effort": 0,
      "stat": {
        "name": "special-defense",
        "url": "https://pokeapi.co/api/v2/stat/5/"
      }
    },
  ]
}

I wanted to create a function, that returns object with max value of base stat from all API calls (there is an array of data for each Pokemon). Object should look like this:

obj = {
  speed: maxvalue of base.stat,
  special - defense: max of base.stat,
  ...
}

Firstly I made separate assignment to every stat:

valueObject["speed"] = Math.max(...data.map(item => item.stats[0].base_stat));
// data is an array of all fetches

But I feel it can be done in one line, or one for loop. Unfortunately, I can't do that and I'm getting errors all the time. I tried mapping and using for loop:

// Option 1//
for (let i of data[0].stats) {
    valueObject[data[0].stats[i].stat.name] = Math.max(
      ...data.map(item => item.stats[i].base_stat)
    );
  }
//Option 2 (it seems a bit off)//
  valueObject[data[0].stats.map(item => item.stat.name)] = Math.max(
    ...data.map(item => item.stats.map(i => i.base_stat))
  );

//I'm using data[0] to just get property names from any pokemon

So, can you help me figure it out?

EDIT: @mplungjan Ok I edited my post, but it doesn't seem to run anyway and I don't know why.

const maxStatsValues = data => {
  //data array is passed as argument, but its elements look like this:
  data[0] = {
    "stats": [{
        "base_stat": 45,
        "effort": 0,
        "stat": {
          "name": "speed",
          "url": "https://pokeapi.co/api/v2/stat/6/"
        }
      },
      {
        "base_stat": 65,
        "effort": 0,
        "stat": {
          "name": "special-defense",
          "url": "https://pokeapi.co/api/v2/stat/5/"
        }
      },
    ]
  }
  data[1] = {
    "stats": [{
        "base_stat": 72,
        "effort": 0,
        "stat": {
          "name": "speed",
          "url": "https://pokeapi.co/api/v2/stat/6/"
        }
      },
      {
        "base_stat": 90,
        "effort": 0,
        "stat": {
          "name": "special-defense",
          "url": "https://pokeapi.co/api/v2/stat/5/"
        }
      },
    ]
  }
  let obj = {};
  data[0].stats.forEach(x => {
    obj[x.stat.name] = Math.max(obj[x.stat.name] | 0, x.base_stat)
  })
  console.log(obj);
  //my code: 
  // let valueObject = {};
  //   for (let i of data[0].stats) {
  //    valueObject[data[0].stats[i].stat.name] = Math.max(
  //      ...data.map(item => item.stats[i].base_stat)
  //    );
  //  }
  // return valueObject;

  return (obj);
};

4
  • Please click edit again and then post a snippet of a runnable script with input and show us expected output Commented May 15, 2019 at 13:19
  • For that kind of operations, array.reduce is probably the most suitable method. Commented May 15, 2019 at 13:19
  • @mplungjan I'm sorry but I don't know how. How can I make this runnable, if data array is fetched from API? Commented May 15, 2019 at 13:37
  • You already have example data. Add the JS to that data in a minimal reproducible example Commented May 15, 2019 at 14:00

1 Answer 1

1

try

valueObject = data.flatMap(x=>x.stats);
valueObject.forEach(x => {
  obj[x.stat.name] = Math.max(obj[x.stat.name] | 0, x.base_stat)
})

let data = [];
data[0] = {
  "stats": [{
      "base_stat": 45,
      "effort": 0,
      "stat": {
        "name": "speed",
        "url": "https://pokeapi.co/api/v2/stat/6/"
      }
    },
    {
      "base_stat": 65,
      "effort": 0,
      "stat": {
        "name": "special-defense",
        "url": "https://pokeapi.co/api/v2/stat/5/"
      }
    },
  ]
}
data[1] = {
  "stats": [{
      "base_stat": 72,
      "effort": 0,
      "stat": {
        "name": "speed",
        "url": "https://pokeapi.co/api/v2/stat/6/"
      }
    },
    {
      "base_stat": 90,
      "effort": 0,
      "stat": {
        "name": "special-defense",
        "url": "https://pokeapi.co/api/v2/stat/5/"
      }
    },
  ]
}

let obj = {};
valueObject = data.flatMap(x=>x.stats);
valueObject.forEach(x => {
  obj[x.stat.name] = Math.max(obj[x.stat.name] | 0, x.base_stat)
})

console.log(obj);

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

5 Comments

What does | mean? I don't think I've seen it before.
this is bit "or" - we use it here in case when value in obj is undefined - numer|0 = number (not change number), undefined|0 = 0 (return zero) e.g. type in console 5|0 and undefined|0
Ah right. I didn't see this operator in JS yet. And what is obj now?
Well I changed valueObject to data[0] because I'm passing data array as argument into the function. It created an object with proper names, but values are incorrect. attack: 49 defense: 49 hp: 45 special-attack: 65 special-defense: 65 speed: 45 Max values are about 200 for each. They are also strangely repeated twice.
Ok I added whole function at the bottom of original question

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.