Sunday, July 12, 2015

Calling JavaScript inner array methods

JavaScript array methods may be placed inside an outer array method. When the outer method is run, the inner method is run against the current array element. In this post, the array that will be used is still the objects containing computer units issued to persons. The objective is to determine the percentage of an individual free HD space against the total HD free space:


The standard approach using a for() loops would be as follows:

<script>
 var units =[
 {name: "Ernie", GBHD: 500, GBHDFree: 300, OS: "Windows"}, 
 {name: "Bert", GBHD: 800, GBHDFree: 350, OS: "MacOS"}, 
 {name: "Kermit", GBHD: 600, GBHDFree: 380, OS: "Windows"},
 {name: "Oscar", GBHD: 450, GBHDFree: 200, OS: "Windows"},
 {name: "Grover", GBHD: 700, GBHDFree: 300, OS: "MacOS"}, 
 {name: "Count", GBHD: 700, GBHDFree: 250, OS: "MacOS"}
 ];
 
 var totalFree = 0;
 
 for(var i =0; i < units.length; i++){
  totalFree += units[i].GBHDFree;
 }
 
 var freePercent = [];
 
 for(var i =0; i < units.length; i++){
  freePercent.push((units[i].GBHDFree/totalFree) * 100);
 }
 
 console.log(freePercent);
 </script>

An alternative approach is to use the array map() method to create a parallel array to the units array. The map() method calls a function that goes through each object element and determines the elements free HD space.


The function then calls a combine units array map() and reduce() methods. The map() creates a parallel array of free HD space for each units object element. The reduce() computes the total of each element (Free HD space) in the parallel array.


The combine map() and reduce() are the inner methods called by the function in the outer map() method. The code snipper is listed below:
<script>
 var units =[
 {name: "Ernie", GBHD: 500, GBHDFree: 300, OS: "Windows"}, 
 {name: "Bert", GBHD: 800, GBHDFree: 350, OS: "MacOS"}, 
 {name: "Kermit", GBHD: 600, GBHDFree: 380, OS: "Windows"},
 {name: "Oscar", GBHD: 450, GBHDFree: 200, OS: "Windows"},
 {name: "Grover", GBHD: 700, GBHDFree: 300, OS: "MacOS"}, 
 {name: "Count", GBHD: 700, GBHDFree: 250, OS: "MacOS"}
 ];
 var getPercentageFree = function(unit){
  var free = unit.GBHDFree;
  var totalFree = units.map(function(unit){return unit.GBHDFree}).reduce(function(start, current){
   return start + current;
  }, 0);
  return (free / totalFree) * 100;
 }
 
 console.log(units.map(getPercentageFree));
 
 </script>

The full code is available at:
https://github.com/jundolor/JavaScript/blob/master/callinginnerarraymethods.html

Monday, July 6, 2015

Combining JavaScript Array Methods filter() and reduce()

JavaScript array methods may be combined to generate a result. The code study in this post will filter selected array elements and summarize the data. The JavaScript array methods that will be combined are filter() and reduce().

The array which will be the subject of the code study is shown below:


Each element of the array is an object with key-value pairs. The idea of the array is to provide information on computers that have been issued to various persons., The name key identifies the person, GBHD stands for Giga Byte HD- the total capacity of the HD, GBHDFree stands for Guga Byte HD Free-meaning the free space on the HD, and OS-the operating system of the computer

Using method filter(), as shown in the code snippet below, the array is narrowed down to computer units with MacOS as the operating system:
      
<script>
 var units =[
 {name: "Ernie", GBHD: 500, GBHDFree: 300, OS: "Windows"}, 
 {name: "Bert", GBHD: 800, GBHDFree: 350, OS: "MacOS"}, 
 {name: "Kermit", GBHD: 600, GBHDFree: 380, OS: "Windows"},
 {name: "Oscar", GBHD: 450, GBHDFree: 200, OS: "Windows"},
 {name: "Grover", GBHD: 700, GBHDFree: 300, OS: "MacOS"}, 
 {name: "Count", GBHD: 700, GBHDFree: 250, OS: "MacOS"}
 ];
 
 var filterOS = function(u){
  return u.OS == "MacOS"
 }
 
 console.log("MacOS Units:" ,units.filter(filterOS));
 //MacOS Units: {name: Bert...}, {name: Grover...}, {name: Count...}
 
</script>

The method filter() calls the function filterOS(). Each array element, an object is passed to the parameter. The function returns back the object has "MacOS" as the value to the OS key. All other objects are filtered out. An array of objects with key-value pair of OS: "MacOS" is returned. Note that the original array is retained.

The method reduce(), as shown in the code snippet below calls the function mostHDFree(). The function, in turn, goes thru each array element, an object, to see which has the biggest GBHDFree value.

<script>
 var units =[
 {name: "Ernie", GBHD: 500, GBHDFree: 300, OS: "Windows"}, 
 {name: "Bert", GBHD: 800, GBHDFree: 350, OS: "MacOS"}, 
 {name: "Kermit", GBHD: 600, GBHDFree: 380, OS: "Windows"},
 {name: "Oscar", GBHD: 450, GBHDFree: 200, OS: "Windows"},
 {name: "Grover", GBHD: 700, GBHDFree: 300, OS: "MacOS"}, 
 {name: "Count", GBHD: 700, GBHDFree: 250, OS: "MacOS"}
 ];
 
 
 var mostHDFree = function(start, current){
  if(start.GBHDFree > current.GBHDFree) return start;
  else return current;
 }
 
 console.log("Unit with most HD free space",units.reduce(mostHDFree));
 //Unit with most HD free space {name: "Kermit", GBHD: 600, GBHDFree: 380, OS: "Windows"}
</script>

The methods filter() and reduce() may be combined to determine what objects with key-value pair of OS: "MacOS" has the most GBHDFree value.

JavaScript starts with the leftmost method and soon as a result is generated, calls the next method to the right, passing the generated result. The cycle will continue for additional methods to the right.

In the case of the filter() and reduce method() combine, the filter() returns an array of objects with OS: "MacOS". The array is passed to the reduce() method which selects the object with the most GBHDFree value.

The code snippet is listed below:
<script>
 var units =[
 {name: "Ernie", GBHD: 500, GBHDFree: 300, OS: "Windows"}, 
 {name: "Bert", GBHD: 800, GBHDFree: 350, OS: "MacOS"}, 
 {name: "Kermit", GBHD: 600, GBHDFree: 380, OS: "Windows"},
 {name: "Oscar", GBHD: 450, GBHDFree: 200, OS: "Windows"},
 {name: "Grover", GBHD: 700, GBHDFree: 300, OS: "MacOS"}, 
 {name: "Count", GBHD: 700, GBHDFree: 250, OS: "MacOS"}
 ];
 
 var filterOS = function(u){
  return u.OS == "MacOS"
 }
 
 var mostHDFree = function(start, current){
  if(start.GBHDFree > current.GBHDFree) return start;
  else return current;
 }
 
 console.log("MacOS with most HD space free",units.filter(filterOS).reduce(mostHDFree));
 //MacOS with most HD space free {name: "Bert"...}, 
</script>

The full code can be downloaded at:
https://github.com/jundolor/JavaScript-Combine-Array-Methods/blob/master/index.html