array

15 things you need to know be master in JS array

need to add some junk text here...

first draft published: December 25, 2013

If you have hard time to follow this video, you can see the content below. Things you will learn-

  1. Best way to create Array
  2. Don't randomly insert by index
  3. use right index to insert
  4. push multiple
  5. unshift multiple
  6. Don't blindly set length
  7. IndexOf: type and instance sensitive
  8. IndexOf Extra parameter
  9. slice splice
  10. delete dont delete
  11. map, forEach, filter, some, every
  12. use build in function as callBack
  13. real length by reduce
  14. isArray
  15. Array like object
  16. Array methods in string
  17. sort, reverse (not added)
  18. join, concat (not added)

1. Best way to Create Array

using constructor:

One of the ways to create array is to call the new Array() constructor. Additionally, you can set array length inside constructor. However, this is not recommended if you are not sure you will use the whole array. As this will create an array with "undefined" elements. Besides, you can pass elements.

If you pass more than one elements in comma seperation, those would initial elements and length of the array would be number of elements you passed.


var myArr = new Array();
//nor
var myArr = new Array(100);
> myArr;
  = [undefined × 100]
//nor
var myArr2 = new Array(2,3,4,5);
> myArr;  
  = [2, 3, 4, 5]
  
better alternative:

rather construct it as empty array. if you know intial elements, its recommended to put them there rather inserting them later.


var myArr = [];

//or, create with elements if you know
var myArr2 = ['You', 'Are', 'the', 'Best' ];    
  
ref: Hardly use new, Sparse vs Dense Array

2. Don't randomly insert by Index

if you insert elements in an arry by index. Please make sure you insert the element in the right place. If you just put an index much higher than the length of the array, JavaScript will put "underfined" elements in between and waste a lot of memory


var myArr = [1, 2, 3, 4];

> myArr.length;
  = 4
//just enter an element in higher index
myArr[68] = 69;
> myArr.length;
  = 69
> myArr;
  =[1, 2, 3, 4, undefined × 64, 69]
  

3. use right index to insert

Only use positive integer as Index:

if you use, negative (-ve) integer, float number or string as index, you will see it in array. even for loop will not display these. In fact, only use positive interger as index. Javascript will not give any error, they will simply be lost when you check array in bare eye. However they sticks, you can read as property or by using a for-in loop. or use dir() in the browser.


var myArr = [1,2,3,4];
myArr[-7] = -7;
myArr[2.5] = 3.5;
myArr['myDude'] = 'thatJSDude';

myArr.length;
  = 4
myArr;
  = [1, 2, 3, 4]  
  

However you can read those


var myArr = [1,2,3,4];

>myArr[169];
  = undefined  
>myArr[2.5];
  = 3.5
>myArr['myDude'];
  = "thatJSDude"
>myArr[-7];
  = -7
  

though u can access those elements by non-positive integer index. you will not see those in the array and for loop will not found those


for(var i=0, len = myArr.length; i<len; i++){
   console.log(myArr[i]);
}
 = 1
 = 2
 = 3
 = 4
  
To soleve this problem:

If you have random index, use object/ Associated Array other than array. if you are looping, use for in loop


var myObj = {};
myObj[-7] = 7;
myObj[68] = 69;

> myObj;
  = Object {68: 69, -7: 7}

//or use for in loop. But for in loop has its own issues
for(var i in myArr){
  console.log(myArr[i]);  
}  
  

talk about dir(myArr)

ref: Can't Trust Array, misleading length

4. push multiple

push inserts elements in the tail and returns updated length of the array

you know you can push one at a time. do you know you can push more than one at a time. But dont push an array, that will be one element of the whole array


var family= ['william', 'kate'];
family.push('prince George', 'princess Nevada');
 = 4
> family;
  = ["william", "kate", "prince George", "princess Nevada"]

//don't insert an array, if u dont mean it
family.push(['children', 'of', 'duke']);

> family
  = ["william", "kate", "prince George", "princess Nevada", Array[3] ]

>family.length;
  = 5  
  

pop just removes the last element and returns it. if there is no element in left, it returns undefined.

5. unshift multiple

unshfit inserts elements at the head (beginning) of the array and returns updated length of the array. you can insert multiple property at the same time


var bigFamily = ['Dad', 'uncle', 'me without gf'];
bigFamily.unshift("Dad's gf");
 = 4
> bigFamily;
  = ["Dad's gf", "Dad", "uncle", "me without gf"]

bigFamily.unshift('grandPa', 'grandMa');
 = 6
bigFamily;
  = ['grandPa', 'grandMa', "Dad's gf", "Dad", "uncle", "me without gf"]
  

//be careful to unshift array. it will be just one element
bigFamily.unshift(["Uncle's gf", 'her daughter']);

bigFamily
  = [ Array[2], "grandPa", "grandMa", "Dad's gf", "Dad", "uncle", "me without gf"]
> bigFamily.length;
  = 7
  

shift will return you the first element of the array and will remove it. shift reduces the array length by 1. unshift and shift is slower than push pop

6. Don't blindly set length

array.length if you only want to read it


var myArr = ['javaScript', 'is', 'my', 'favorite', 'language' ];
> myArr.length;
  = 5  
  
Don't blindly set length:

if you set the length you resize the array. If you set length to a number higher than the actual length, insert "underfined" elements. On the otherhand, if you set length lower than the actual length, it removes all the elements after the newly set length. So, be careful to set array.length


myArr.length = 8;
> myArr;
  = ["javaScript", "is", "my", "favorite", "language", undefined × 3] //three undefined elements inserted

myArr.length = 4;
> myArr;
  = ["javaScript", "is", "my", "favorite"] //removed 4 elements

  

7. IndexOf: type and instace sensitive

indexOf compare type of the element and instance of the element. For the second example, though {b:2} looks identical, they are two seperate instance hence indexOf will not find it in the array. similarly [3] in the third example and inside indexOf are two seperate instance of array. though they contain same element inside, they are two seperate instance


[1,2,3,4].indexOf(3);
 = 2
 //'3' is a string where 3 is number
[1,2,3,4].indexOf('3');
 = -1

[{a:1}, {b:2}].indexOf({b:2});
 = -1

 //similarly
 [[1], [2], [3]].indexOf([3])
 = -1
  

to solve the problem of object. you have to hold the reference


var myObj = {a:1}, 
    urObj = {b:2};

[myObj, urObj].indexOf(urObj);
 = 1    
  

8. indexOf extra fromIndex

good part of indexOf is that you can provide second parameter to tell from where indexOf should start searching for ur element


[1,2,3,4,5,4,3,2,1].indexOf(3)
= 2

[1,2,3,4,5,4,3,2,1].indexOf(3, 4)
= 6

[1,2,3,4,5,4,3,2,1].indexOf(3, 7)
= -1
  

samething is true for lastIndexOf. use ur own brain to think how that will work. or open console and check it out.

ref: es5:indexOf

9. slice & splice

slice

slice retuns the sliced array but dont change the original array


var GFs = ['Winter', 'Spring', 'summer', 'fall', 'rain', 'harvest'];

GFs.slice(2);
 = ['summer', 'fall', 'rain', 'harvest']

GFs.slice(2, 2);
 = ['summer', 'fall'] 

GFs
 = ['Winter', 'Spring', 'summer', 'fall', 'rain', 'harvest']; 
  
splice

splice change the original array


var GFs = ['Winter', 'Spring', 'summer', 'fall', 'rain', 'harvest'];

GFs.splice(2);
 = ['summer', 'fall', 'rain', 'harvest']
GFs 
 = ['Winter', 'Spring']

GFs.splice(2, 2);
 = ['summer', 'fall'] 

GFs.splice(2, 2, 'Texas GF', 'Florida GF', 'Hawai GF')
 = ["summer", "fall"]

 GFs
  =["Winter", "Spring", "Texas GF", "Florida GF", "Hawai GF", "rain", "harvest"] 
  

10. delete dont delete

delete just creates a hole in ur array. dont delete element, use splice/ slice


var myArr = [1,2,3,4,5,6,7];
delete myArr[3]
 = true
myArr
 = [1, 2, 3, undefined × 1, 5, 6, 7]
  

Basic Array method

callback function of map, filter, some, every, forEach has three parameters: elem, index, arr. And you can optionally pass "this" as second argument of these Array method.

forEach

forEach dont return anything. it just run the callback functionf or each element of the array


> [1,2,3].forEach(function(elem, index, arr){
    console.log(elem);
  });
  = 1
  = 2
  = 3
    
  
map

returns new array by executing the callback function for each elements of the array


> [1,2,3].map(function(elem, index, arr){
    return elem * elem;
  });
  = [1, 4, 9];
filter

if the condition is true for an element, element is picked for the return array


> [1,2,3,4,5,6,7].filter(function(elem, index, arr){
    return index % 2==0;
  });
  = [1, 3, 5, 7]
some

if any of element in the arrya fulfil the condition, some will return true else will return false


  >[1,2,3, 4].some(function(elem, index, arr){
    return elem >3;
  });
  = true;
every

it will return true if every elements in the array fulfil the condition. else return false


>[1,2,3, 4].every(function(elem, index, arr){
    return elem >3;
  });
  = false;

>[1,2,3, 4].every(function(elem, index, arr){
    return elem >0;
  });
  = true;  

11.use build in function


> ["Happy", 0, "New", "", "Year", false].filter(Boolean);
  = ["Happy", "New", "Year"]
  

ref: es5 array extra

reduce

reduce cache the value. for example u want to get the sum of all the element. alternatively, you can initially


[1, 2, 3, 4].reduce(function(sum, el, idx, arr){
  return sum + el;
})
 = 10

[1, 2, 3, 4].reduce(function(sum, el, idx, arr){
  return sum + el;
}, 100)
 = 110
  

12. real length by reduce

talk about reduce here

 
> ["hello", , , , , "javaScript"].reduce(function(count){ 
    return count + 1; 
  }, 0);
  = 2 
  

13. check array


> typeof []
  = "object"
> typeof {}
  = "object"  

> Array.isArray([]);
  = true
> Array.isArray({});
  = false
  

14. deal with Array-like objects


function foo(){
  console.log(arguments, 'len', arguments.length, '2nd', arguments[1])
}

foo(1, 2, 3,4)
 = [1, 2, 3, 4] "len" 4 "2nd" 2 
  

function foo(){
  console.log(Array.isArray(arguments));
  arguments.push(5);
  console.log(arguments, 'len', arguments.length, '2nd', arguments[1])
}
foo(1, 2, 3,4)
 = false
 = TypeError: Object #<Object> has no method 'push'
  

function foo(){
  var args = Array.prototype.slice.call(arguments);
  args.push(5);
  console.log(args, 'len', args.length, '2nd', args[1])
}

foo(1, 2, 3,4)
 = [1, 2, 3, 4, 5] "len" 5 "2nd" 2 
  

15. array method in string


var dd = 'that JS Dude';

dd.filter(function (el, idx){
  return idx>7;
})
 = TypeError: Object that JS Dude has no method 'filter'
  

[].filter.call(dd, function(el, idx){
 return idx>7;
})
 = ["D", "u", "d", "e"]
  

for more: Fun with JS Array, WAT