Must use JavaScript Array Functions – Part 2

In Must use Javascript Array Functions – Part 1, we discussed two array functions namely Array.Prototype.Every() and Array.prototype.some(). It is important to note that both of these array functions accessed the array elements but did not modify/change the array itself. Today we are going to look at 2 array methods which modify the array and return the modified array.

Array.Prototype.filter()

Description: Array.prototype.filter() is used to get a new array which has only those array elements which pass the test implemented by the callback function. It accepts a callback function as argument. This callback function has to return a true or false. Elements for which the callback function returned true are added to the newly returned array.



Syntax:arr.filter(callback[, thisArg])

Parameters:
callback: callback function to be called for each element of the array arr
 currentValue: The value of the elements being processed currently
 index(optional): Index of the currentValue element in the array starting from 0
 array(optional): The complete array on which Array.prototype.filter() is called

thisArg: Context to be passed as this when used while executing the callback function. If no context is passed, undefined will be used as default value.

Sample use Cases:
1. Scenario where user has to remove all null values from an array.
2. Scenario where user has to filter out the array based on value of a particular property of objects in the array.

Example:
1.Function to filter out the students who got more than 80 percent marks.
Naïve Method using loop

filter_none

edit
close

play_arrow

link
brightness_4
code

<script>
    function fnFilterStudents_loop(aStudent){
        var tempArr = [];
        for(var i = 0 ; i< aStudent.length; i ++){
            if(aStudent[i].fPercentage > 80.0){ tempArr.push(aStudent[i]);}
            }
        return tempArr;
    }
    aStudent = [
        {sStudentId : "001" , fPercentage : 91.2},
        {sStudentId : "002" , fPercentage : 78.7},
        {sStudentId : "003" , fPercentage : 62.9},
        {sStudentId : "004" , fPercentage : 81.4}];
          
    console.log(fnFilterStudents_loop(aStudent));
</script>

chevron_right


Output:

[{sStudentId : "001" , fPercentage : 91.2},
{sStudentId : "004" , fPercentage : 81.4}];

Using Array.prototype.filter()

filter_none

edit
close

play_arrow

link
brightness_4
code

<script>
    function fnFilterStudents_filter(aStudent){
        return aStudent.filter(function(oStudent){
            return oStudent.fPercentage > 80.0 ? true : false;
              
        });
    }
    aStudent = [
        {sStudentId : "001" , fPercentage : 91.2},
        {sStudentId : "002" , fPercentage : 78.7},
        {sStudentId : "003" , fPercentage : 62.9},
        {sStudentId : "004" , fPercentage : 81.4}];
          
    console.log(fnFilterStudents_filter(aStudent));
</script>

chevron_right


Output:

[{sStudentId : "001" , fPercentage : 91.2},
{sStudentId : "004" , fPercentage : 81.4}];

2. Function to remove undefined elements from an array

filter_none

edit
close

play_arrow

link
brightness_4
code

<script>
    function removeUndefined(myArray){
        return myArray.filter(function(element, index, array){
            return element;
        });
    }
      
    var arr = [1,undefined,3,undefined,5];
      
    console.log(arr);
      
    console.log( removeUndefined(arr));
</script>

chevron_right


Output:


[1,undefined,3,undefined,5];
[1,3,5];

In the callback function of above example, we are returning element directly. So if the element has value, it will be treated as true and if element is undefined, it will be automatically treated as false.

Array.Prototype.map()

Description:Array.prototype.map() is used to modify each element of the array according to the callback function. Array.prototype.map() calls the callback function once for each element in the array in order. The point to note is that callback function is called on indexes of elements who has assigned value including undefined.

Syntax:arr.map(callback[, thisArg])

Parameters:
callback : Callback function to be called for each element of the array arr
 currentValue: The value of the elements being processed currently
 index(optional): Index of the currentValue element in the array starting from 0
 array(optional): The complete array on which Array.prototype.map() is called

thisArg: Context to be passed as this when used while executing the callback function. If no context is passed, undefined will be used as default value.

Sample use Cases:
1. Scenario where user has to reduce each amount in an array by a specific tax value
2. Scenario where user has to create a new property of every object in an existing array of objects.

Example:

1.Function to add property bIsDistinction to each object in the array.

Using Loop


filter_none

edit
close

play_arrow

link
brightness_4
code

<script>
    function fnAddDistinction_loop(aStudent){
        for(var i = 0 ; i< aStudent.length; i ++){
            aStudent[i].bIsDistinction = (aStudent[i].fPercentage >= 75.0) ? true : false;
            }
        return aStudent;
    }
    aStudent = [
        {sStudentId : "001" , fPercentage : 91.2},
        {sStudentId : "002" , fPercentage : 78.7},
        {sStudentId : "003" , fPercentage : 62.9},
        {sStudentId : "004" , fPercentage : 81.4}];
           
    console.log(fnAddDistinction_loop(aStudent));
</script>

chevron_right


Output:

[{sStudentId : "001" , fPercentage : 91.2 , bIsDistiction : true},
 {sStudentId : "002" , fPercentage : 78.7 , bIsDistiction : false},
 {sStudentId : "003" , fPercentage : 62.9 , bIsDistiction : false},
 {sStudentId : "004" , fPercentage : 81.4 , bIsDistiction : true}];

Using Array.prototype.map()

filter_none

edit
close

play_arrow

link
brightness_4
code

<script>
    function fnAddDistinction_map(aStudent){
        return aStudent.map(function(student, index, array){
            aStudent.bIsDistinction = (aStudent.fPercentage >= 75.0) ? true : false;
            return aStudent;
        });
    }
    aStudent = [
        {sStudentId : "001" , fPercentage : 91.2},
        {sStudentId : "002" , fPercentage : 78.7},
        {sStudentId : "003" , fPercentage : 62.9},
        {sStudentId : "004" , fPercentage : 81.4}];
           
    console.log(fnAddDistinction_map(aStudent));
</script>

chevron_right


Output:

[{sStudentId : "001" , fPercentage : 91.2 , bIsDistiction : true},
 {sStudentId : "002" , fPercentage : 78.7 , bIsDistiction : false},
 {sStudentId : "003" , fPercentage : 62.9 , bIsDistiction : false},
 {sStudentId : "004" , fPercentage : 81.4 , bIsDistiction : true}];

2. Scenario where Array.prototype.Map() is used with standard JavaScript functions.

For example, with Math.sqrt to calculate square root of each element in an array or to parse string values to float.

filter_none

edit
close

play_arrow

link
brightness_4
code

[1,4,9].map(Math.sqrt); // Output : [1,2,3]
["1.232","9.345","3.2345"].map(parseFloat) // Output : [1.232, 9.345, 3.2345]

chevron_right


One has to be careful while using Array.prototype.map() with standard functions because something like this can happen.

filter_none

edit
close

play_arrow

link
brightness_4
code

["1","2","3"].map(parse.Int);
//Output : [1, NaN, NaN]

chevron_right


Why did the above code snippet return NaN? This happened because parseInt function accepts two arguments, First one being the element to be parsed to Integer and second as the radix which acts as base for conversion. When we use it with Array.prototype.map(), although the first argument is the element, the second argument is the index of the array element being processed currently. For first iteration, the index being 0 is passed as radix to parseInt which defaults it to 10 and thus you see first element parsed successfully. After that it gets messed up.

Below is the fix for above mess up.

filter_none

edit
close

play_arrow

link
brightness_4
code

["1","2","3"].map(function(val{return parseInt(val,10)});
// output : [1, 2, 3]

chevron_right


All code snippets used in this tutorial is available at: https://github.com/hjaintech/GeeksForGeeks/blob/master/Array_Functions_2.html


As shown in the above examples, both Array.prototype.filter() and Array.prototype.map() can be implemented using for loops. But in the above scenarios, we are trying to work on very specific use cases. Keeping a counter variable, then a checking against array length and then incrementing the counter variable. Keeping these things in mind is not only a hassle, but also make code prone to bugs. For example, developer might accidently misspell “array.length” as “array.lenght”. So as a rule of thumb, the best way to avoid programming bugs is to reduce the number of things that you are keeping track of manually. And these Array Functions do just that.

Browser support is really good for these functions but they are still not supported in IE8 or below as these array functions were introduced in ECMAScript 5. If you need to use it for older browsers as well, then you can either use es5-shim or any library like Underscore or Lodash can come to your rescue which has equivalent utility function.

Must use JavaScript Array Functions -Part 3

Additionally, if you wish to dive deeper into the above functions, you can refer to following official links
1. http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.20
2. http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.19

About the author:

“Harshit is a technology enthusiast and has keen interest in programming. He holds aharshit-jain  B.Tech. degree in Computer Science from JIIT, Noida and currently works as Front-end Developer at SAP. He is also a state level table tennis player. Apart from this he likes to unwind by watching movies and English sitcoms. He is based out of Delhi and you can reach out to him at https://in.linkedin.com/pub/harshit-jain/2a/129/bb5

If you also wish to showcase your blog here,please see GBlog for guest blog writing on GeeksforGeeks.



My Personal Notes arrow_drop_up


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.