FCC Bonfire Series 140: Map the Debris

Today’s bonfire, once again, will have us deal with objects. This time, in Map the Debris, we must write a function that, given an array of elements (satellites) and their average altitudes, must return their orbital periods.

The orbital period of a satellite orbiting a planet is the time that it takes for said satellite to complete a whole orbit around the planet. To ease our task, we will begin by abstracting this piece of logic into a function that will get us the orbital period for an individual satellite. After that, we’ll use this function to get the orbital period of the elements in an array.

To calculate the orbital period of a small body orbiting a central, large body, we will use the following data:

  • GM: Standard gravitational parameter of the central body (provided to us)
  • Average distance between the satellite and the centre of the central body.

The average distance is but the sum of the central body’s radius and the average distance from it’s surface to the satellite. In short:

Orbital Period = 2 * π * √(avgDist³ / GM)

In JavaScript, it would look like so:

var orbitalPeriod = 2 * Math.PI * Math.sqrt(Math.pow(avgDist, 3) / GM);
  • Math.PI is equal to π (pi)
  • Math.sqrt(number) is used to calculate the square root of the inner result, Math.sqrt(4) = √4 = 2
  • Math.pow(base, exponent) takes two arguments, base and exponent. It will return the base to the exponent power, Math.pow(3, 2) = 3² = 9

Now that we are JavaScript math geniuses, let’s create a function, that given the distance of an element from the surface of a planet, the standard gravitational parameter of the planet (GM) and radius of the planet, returns the orbital period. Remember, that we must sum both, distance from the surface and radius of the planet to get the total distance from the planet’s core:

function getOrbitalPeriod(avgAltitude, planetRadius, GM) {
  return 2 * Math.PI * Math.sqrt(Math.pow(avgAlt + planetRadius, 3) / GM);
}

 

Good! Just a little note! We are asked to round this number to the closest integer. We can round numbers in JavaScript using the following methods:

  • Math.floor(): Returns the largest integer less that or equal to the given number.
    Math.floor(6.1); //-> 6
    Math.floor(6.7); //-> 6
  • Math.ceil(): Returns the lowest integer greater than or equal to the given number.
    Math.ceil(5.2); //-> 6
    Math.ceil(5.7); //-> 6
  • Math.round(): Returns the value of the number rounded to the nearest integer.
    Math.round(5.3); //-> 5
    Math.round(5.5); //-> 6
    Math.round(5.7); //-> 6

     

It would seem that Math.round() could do the job, let’s round our result before we return it:

function getOrbitalPeriod(avgAltitude, planetRadius, GM) {
  return Math.round(2 * Math.PI * Math.sqrt(Math.pow(avgAltitude + planetRadius, 3) / GM));
}

 

Great! Now that we can easily compute the orbital period of any given object (we can even use it for different planets since we are using GM and radius as variables!) let’s apply this to an array of satellites. We are going to use the Array.prototype.map() method, which applies a function to every element inside an array, and returns the result. Remember to define the getOrbitalPeriod function we just created inside our wrapping function:

function orbitalPeriod(array) {
  var GM = 398600.4418,             // These two are given to us!
      earthRadius = 6367.4447;

  var result = array.map(function(currentElement) {
    // Do something with current element!
  });

  return result;

  function getOrbitalPeriod(avgAltitude, GM, planetRadius) {
    return Math.round(2 * Math.PI * Math.sqrt(Math.pow(avgAltitude + planetRadius, 3) / GM));
  }
}

 

Array map is incredibly useful. We can operate on the current element and transform it however we want. In this case, we are getting objects that contain a name and avgAlt, we want to return objects that have the name and orbital period. Let’s see how it’s done:

function orbitalPeriod(array) {
  var GM = 398600.4418,
      earthRadius = 6367.4447;

  var result = array.map(function(currentElement) {
    return {
      name: currentElement.name,
      orbitalPeriod: getOrbitalPeriod(currentElement.avgAlt, GM, earthRadius)  // We get the orbital radius using the previous function!
    }
  });

  return result;

  function getOrbitalPeriod(avgAltitude, GM, planetRadius) {
    return Math.round(2 * Math.PI * Math.sqrt(Math.pow(avgAltitude + planetRadius, 3) / GM));
  }
}

 

We can even return the result of the map method without using an unnecessary variable:

function orbitalPeriod(array) {
  var GM = 398600.4418,
      earthRadius = 6367.4447;

  return array.map(function(currentElement) {
    return {
      name: currentElement.name,
      orbitalPeriod: getOrbitalPeriod(currentElement.avgAlt, GM, earthRadius)  // We get the orbital radius using the previous function!
    }
  });

  function getOrbitalPeriod(avgAltitude, GM, planetRadius) {
    return Math.round(2 * Math.PI * Math.sqrt(Math.pow(avgAltitude + planetRadius, 3) / GM));
  }
}

 

EXTRA:

If you don’t feel to conformable using the map method, try using a forEach and push instead!

function orbitalPeriod(arr) {
  var results = [];
  var GM = 398600.4418,
      earthRadius = 6367.4447;

  arr.forEach(function(element) {
    results.push({
      name: element.name,
      orbitalPeriod: getOrbitalPeriod(element.avgAlt, GM, earthRadius)
    });
  });

  return results;

  function getOrbitalPeriod(avgAlt, GM, planetRadius) {
    return Math.round(2 * Math.PI * Math.sqrt(Math.pow(avgAlt + planetRadius, 3) / GM));
  }
}

 

Good luck and happy coding!