繼續我的第二遍《javascript高級程序設計第三版》,今天要做的筆記是array
一、數組的操作
1、數組的創建:
var colors= new Array(); //創建一個數組
var colors = new Array(20); //創建一個數組並指定長度
var colors = new Array("red","blue","green"); //創建一個數組並賦值
airbnb的規范建議,我們在創建數組的時候,最好采用省略new操作符的形式,如下:
airbnb網址:https://github.com/airbnb/javascript
// bad var items = new Array(); // good var items = [];
2、數組的元素的訪問
var colors=["red","blue","green"] alert(colors[0]); //顯示第一項 colors[2]="black"; //修改第三項 colors[3]="brown"; //新增第四項
1、通過方括號加索引值訪問
2、設置在索引值在范圍內的其他值,可以替換指定位置的值
3、如果索引值超過了數組現有的項數,數組會自動增加到該索引值加1的長度,如代碼中的新增第四項
3、數組中添加元素:
有以下幾種方法:
1、push,將元素添加到數組的末尾:
var colors=[]; colors.push("red","blue"); console.log(colors); //[red,blue]
2、索引值超過了數組現有的項數來添加。因為索引值是從0算起的,所以數組的長度總比索引值大1
var colors=["red","blue","green"]; colors[colors.length]="black"; console.log(colors); //["red","blue","green","black"];
3、unshift,將元素添加到數組的前端
var colors=["red","blue","green"];
colors.unshift("black");
console.log(colors); //["black","red","blue","green"];
4、splice ,可以指定位置插入任意數組的項。至少需要三個參數:起始位置,0和要插入的項.當然也可以插入多項。
var arr = ["George","John","Thomas","James","Adrew","Martin"]; arr.splice(2,0,"William") console.log(arr); //["George","John","William","Thomas","James","Adrew","Martin"];
4、數組的刪除、替換
數組的刪除:
1、arrayObj.pop(); //移除最后一個元素並返回該元素值
2、arrayObj.shift(); //移除最前一個元素並返回該元素值,數組中元素自動前移
3、arrayObj.splice(start,length); //刪除從指定位置start開始的指定數量length的元素,數組形式返回所移除的元素
4、指定數組的length小於它的長度
var arr = ["George","John","William","Thomas","James","Adrew","Martin"]; var deleteItem1=arr.pop(); console.log(deleteItem1); //Martin console.log(arr); //["George", "John", "William", "Thomas", "James", "Adrew"] var deleteItem2=arr.shift(); console.log(deleteItem2); //George console.log(arr); //["John", "William", "Thomas", "James", "Adrew"] var deleteItem3=arr.splice(0,2); console.log(deleteItem3); //["John", "William"] console.log(arr); //["Thomas", "James", "Adrew"] arr.length=2; console.log(arr); ////["Thomas", "James"]
數組的替換:
array.splice(start,length,"otherValue") 傳三個值,開始替換位置,替換的數量,替換后的值。
var arr = ["George","John","William","Thomas","James","Adrew","Martin"]; var arr2 = ["George","John","William","Thomas","James","Adrew","Martin"]; var deleteItem=arr.splice(0,1,"123"); //返回被替換的值 console.log(deleteItem); //["George"] console.log(arr); // ["123", "William", "Thomas", "James", "Adrew", "Martin"] var deleteItem2=arr2.splice(0,2,"123","456"); //返回被替換的值.可以替換多個值 console.log(deleteItem2); //["George", "John"] console.log(arr2); // ["123", "456", "William", "Thomas", "James", "Adrew", "Martin"]
5、數組的截取、合並和復制
1、截取數組:slice(start,end)
以數組的形式返回被截取部分。不包括end對應的項。
如果省略end,則截取start之后的所有元素。
只傳0,相當於復制了數組
var arr = ["George","John","William","Thomas","James","Adrew","Martin"]; var getArray=arr.slice(1,3); console.log(getArray); //["John", "William"] console.log(arr); //["George", "John", "William", "Thomas", "James", "Adrew", "Martin"] 不影響原數組 var getArray2=arr.slice(1); console.log(getArray2); //["John", "William", "Thomas", "James", "Adrew", "Martin"] console.log(arr.slice(0)); //["George","John","William","Thomas","James","Adrew","Martin"]
2、數組的合並:arrayObj.concat([item1[, item2[, . . . [,itemN]]]]);
將多個數組(也可以是字符串,或者是數組和字符串的混合)連接為一個數組,返回連接好的新的數組。
如果什么也不傳,相當於復制數組。
var arr = ["George","John","William","Thomas","James","Adrew","Martin"]; var arr2=["123","456"]; var arr3=arr.concat(arr2); console.log(arr3); //["George", "John", "William", "Thomas", "James", "Adrew", "Martin", "123", "456"]
6、數組的字符創化: array.join();
返回字符串,這個字符串將數組的每一個元素值連接在一起,中間用傳入的值隔開。
var arr = ["George","John","William","Thomas","James","Adrew","Martin"];
console.log(arr.join(',')); //George,John,William,Thomas,James,Adrew,Martin
console.log(arr.join('-')); //George-John-William-Thomas-James-Adrew-Martin
console.log(arr.join(' ')); //George John William Thomas James Adrew Martin
7、數組的排序:reverse()反序 sort()正序
var arr = [1,5,8,9,6,3]; console.log(arr.reverse()); //[3, 6, 9, 8, 5, 1] console.log(arr.sort()); //[1, 3, 5, 6, 8, 9] console.log(arr.sort().reverse()); //[9, 8, 6, 5, 3, 1]
二、數組的高級用法
1、棧方法和隊列:
棧方法:
棧是一種 LIFO(Last-In-First-Out,后進先出)的數據結構,也就是最新添加的項最早被移除。而棧中項的插入(叫做推入)和移除(叫做彈出) ,只發生在一個位置——棧的頂部。
ECMAScript 為數組專門提供了 push() 和 pop() 方法,以便實現類似棧的行為
var colors = ["red", "blue"];
colors.push("brown"); // 添加另一項
colors[3] = "black"; // 添加一項
alert(colors.length); // 4
var item = colors.pop(); // 取得最后一項
alert(item); //"black"
隊列方法:
隊列數據結構的訪問規則是 FIFO (First-In-First-Out,先進先出) 。
隊列在列表的末端添加項, 從列表的前端移除項。結合使用 shift() 和 push() 方法,可以像使用隊列一樣使用數組。
var colors = new Array(); //創建一個數組
var count = colors.push("red", "green"); //推入兩項
alert(count); //2
count = colors.push("black"); //推入另一項
alert(count); //3
var item = colors.shift(); // 取得第一項
alert(item); //"red"
alert(colors.length); //2
如圖所示:
棧方法:
隊列方法:
2、數組的去重
這個是在實際應用中和面試中經常遇到的問題。所以提供以下的幾種解決辦法:
在介紹去重的方法之前,先了解數組的indexOf方法,因為下面會用到。
indexOf()方法返回在該數組中第一個找到的元素位置,如果它不存在則返回-1。
var a = ['red', 'blue', 'green', 'blue'];
console.log(a.indexOf("blue")); // 1
console.log(a.indexOf("black")); // -1
方法1:遍歷數組法
function unique(array){
var n = [];
for(var i = 0; i < array.length; i++){
//如果當前數組的第i已經保存進了臨時數組,那么跳過,
//否則把當前項push到臨時數組里面
if (n.indexOf(array[i]) == -1){
n.push(array[i]);
}
}
return n;
}
var testArry=[1,2,5,5,6];
console.log(unique(testArry)); //[1, 2, 5, 6]
方法1缺點:IE8以及IE8以下不支持 indexOf
方法2:對象鍵值對法
function unique(array){
var n = {};
var r = [];
var len = array.length;
var val;
var type;
for (var i = 0; i < array.length; i++) {
val = array[i];
type = typeof val;
if (!n[val]) {
n[val] = [type];
r.push(val);
} else if (n[val].indexOf(type) < 0) {
n[val].push(type);
r.push(val);
}
}
return r;
}
var testArry=["hello",2,5,5,6,"hello"];
console.log(unique(testArry)); //["hello", 2, 5, 6]
比較不好理解,稍作解釋:
新建一js對象以及新數組,遍歷傳入數組時,判斷值是否為js對象的鍵,不是的話給對象新增該鍵並放入新數組。
可以看看n返回的是什么: Object {2: ["number"], 5:["number"], 6: ["number"], hello: ["string"]} ,讓數組中的值作為對象的鍵,並讓它的值只有一個數組
方法2優缺點:優點:速度最快。 缺點:占空間最多(空間換時間)
方法3:數組下標判斷法
function unique(array){
var n = [array[0]]; //結果數組
//從第二項開始遍歷
for(var i = 1; i < array.length; i++) {
//如果當前數組的第i項在當前數組中第一次出現的位置不是i,
//那么表示第i項是重復的,忽略掉。否則存入結果數組
if (array.indexOf(array[i]) == i){
n.push(array[i]);
}
}
return n;
}
var testArry=["hello",2,5,5,6,"hello"];
console.log(unique(testArry)); //["hello", 2, 5, 6]
類似方法1,將不重復的放到數組中,然后返回
方法4:給傳入數組排序,排序后相同值相鄰,然后遍歷時新數組只加入不與前一值重復的值。
function unique(array){
// 按從小到到排序
array.sort();
var re=[array[0]];
for(var i = 1; i < array.length; i++){
if( array[i] !== re[re.length-1]) {
re.push(array[i]);
}
}
return re;
}
var testArry=["hello",2,5,5,6,"hello"];
console.log(unique(testArry)); //[2, 5, 6, "hello"]
5.優化遍歷數組法
實現思路:獲取沒重復的最右一值放入新數組。(檢測到有重復值時終止當前循環同時進入頂層循環的下一輪判斷)
function unique(array){
var r = [];
for(var i = 0, l = array.length; i < l; i++) {
for(var j = i + 1; j < l; j++){
if (array[i] === array[j]) {
j = ++i
}
}
r.push(array[i]);
}
return r;
}
var testArry=["hello",2,5,5,6,"hello"];
console.log(unique(testArry)); //[2, 5, 6, "hello"]
方法6、簡單法,類似於方法1.
function unique(array){
var arr=[];
var obj={};
for(var i=0;i<array.length;i++){
if(!obj[array[i]]){
obj[array[i]]=array[i];
arr.push(array[i]);
}
}
return arr;
}
var testArry=["hello",2,5,5,6,"hello"];
console.log(unique(testArry)); //["hello", 2, 5, 6]
因為簡單,也是我最喜歡用的,哈哈
3、迭代方法
ECMAScript5為數組定義了5個迭代方法。
1、forEach 遍歷數組一次對數組中的各個項
可以使用三個參數:數組對象、元素索引以及數組本身
var testArry=["hello",2,5,6];
testArry.forEach(function (item, index, array) {
console.log(item); //hello 2 5 6
console.log(index); // 0 1 2 3
console.log(array); // ["hello",2,5,6] 輸出4遍
});
2、every() 返回一個布爾值(true或false),判斷每個數組項是否符合指定函數的條件,符合為true,反之為false
var testArry=[10,8,5,6];
var isBiggerThan7 = testArry.every(function(ele,index,arr){
return (ele >= 7);
});
if (isBiggerThan7) {
console.log('都大於等於7');
} else {
console.log('不全都大於等於7');
}
//不全都大於等於7
3、some() 返回一個布爾值(true或false),判斷每個數組項是否符合指定函數的條件,只要有任何一項返回為true,就會返回true
var testArry=[10,8,5,6];
var isBiggerThan7 = testArry.some(function(ele,index,arr){
return (ele >= 7);
});
if (isBiggerThan7) {
console.log('有大於等於7的元素');
} else {
console.log('沒有大於等於7的元素');
}
//有大於等於7的元素
4 filter(): 每個數組項調用指定的函數,條件為true的將返到一個新數組中.相當於是篩選數組里面的內容
var testArry=[10,8,5,6];
var BiggerThan7 = testArry.filter(function(ele,index,arr){
if(ele >= 7){
return true;
}
});
console.log(BiggerThan7); //[10, 8]
5、map() 每個數組項調用指定的函數,返回每次函數調用的結果組成一個新數組
用法基本和forEach一樣,但是有個區別,forEach沒有返回值,map有返回值
var testArry=[10,8,5,6];
var newArry1 = testArry.map(function(ele,index,arr){
if(ele >= 7){
return true;
}
});
console.log(BiggerThan7); //[true, true, undefined, undefined]
// -----------------------------------------------------------------------------
var newArry2 = testArry.forEach(function(ele,index,arr){
if(ele >= 7){
return true;
}
});
console.log(newArry2); //undefined
4、歸並方法
ECMAScript5 有2個歸並數組的方法:reduce()和reduceRight()。
1、reduce():從第一項開始逐個遍歷到最后。它接收兩個參數 array.reduce(callback, initialValue),
callback 函數接受4個參數:之前值、當前值、索引值以及數組本身。
initialValue可選,表示初始值。若指定,則當作最初使用的previous值;如果缺省,則使用數組的第一個元素作為previous初始值,同時current往后排一位
(initialValue的用法還不是很清楚。歡迎補充)
var testArry=[10,8,5,6]; var result = testArry.reduce(function(previous, current, index, array){ return previous+current; }); console.log(result); //29
2、reduceRight(): 從數組的最后一項開始,遍歷到數組的第一項。
用法同reduce基本一樣,只是開始的位置從右邊第一位開始,區別僅此而已
var testArry=[10,8,5,6];
var initialValue=10;
var result = testArry.reduceRight(function(previous, current, index, array){
return previous+current;
});
console.log(result); //29
三、數組的算法
獲取最大值和最小值
方法一:遍歷
獲取最大值
function getMax(arr){ if(!(arr instanceof Array)){ return; } var max=arr[0]; for(var i=0,len=arr.length;i<len;i++){ if(arr[i]>max){ max=arr[i]; } } return max; } var maxNum=getMax([1,3,5,7,10]); alert(maxNum); //10
獲取最小值
function getMin(arr){ if(!(arr instanceof Array)){ return; } var min=arr[0]; for(var i=0,len=arr.length;i<len;i++){ if(arr[i]<min){ min=arr[i]; } } return min; } var minNum=getMin([3,3,1,7,10]); alert(minNum); //1
方法二: 原型方法:(利用apply方法來調用原生的Math.max與Math.min方法來求得結果)
獲取最大值:
Array.prototype.getMax=function(){
return Math.max.apply({},this);
}
var maxNum=[1,3,5,7,10].getMax();
alert(maxNum); //10
獲取最小值:
Array.prototype.getMin=function(){ return Math.min.apply({},this); } var minNum=[1,3,5,7,10].getMin(); alert(minNum); //1
數組的排序(從小到大或者從大到小)
sort:直接使用不能達到效果,需要傳個函數
var arr=[3,9,1,7,10]; alert(arr.sort()); // 1,10,3,7,9
需要這樣
function sortArray(a,b){ return a-b; } var arr=[3,9,1,7,10]; var minToMax=arr.sort(sortArray); alert(minToMax); // 1,3,7,9,10 從小到大 var maxToMin=arr.sort(sortArray).reverse(); alert(maxToMin); // 10,9,7,3,1 從大到小
四、es6新增加的數組方法
1、Array.from()
Array.from方法用於將兩類對象轉為真正的數組:類似數組的對象(array-like object)和可遍歷(iterable)的對象(包括es6新增的數據結構Set和Map)。
需要注意以下三點:
1、任何有length屬性的對象,都可以通過Array.from方法轉為數組。
2、傳參為類數組對象 就是類似數組結構的對象,比如key值為數字啊什么的
3、Array.from是通過key作為下標並且參照length屬性大小來填充元素的。當沒有合適的元素插入時就會插入undefined補位。
直接上代碼:
var a = Array.from('hello'); console.log(a);// ['h', 'e', 'l', 'l', 'o'] // 沒有傳length,結果返回了一個空數組,驗證了第一個注意點 var obj={"name":"咸魚","age":"24","sex":"男"} console.log(Array.from(obj)); //[] // 有傳length,但不是類數組,返回三個undefined, 驗證了第二個,第三個注意點 var obj2={"name":"咸魚","age":"24","sex":"男",length: 3}; console.log(Array.from(obj2)); //[undefined, undefined, undefined] // 有傳length,並且對象是類數組 var obj3={"0":"咸魚","1":"24","2":"男",length: 3} console.log(Array.from(obj3)); //["咸魚", "24", "男"] // key值不從0起,驗證了注意點3 var obj4 = { "1":"咸魚","2":"24","3":"男",length: 3}; console.log(Array.from(obj4)); //[undefined, "咸魚", "24"]
2、Array.of();
Array.of方法用於將一組值,轉換為數組
var a=Array.of(3,9,10); var b=Array.of(3); console.log(a); //[3, 9, 10] console.log(b); //[3] console.log(b.length); //1
跟普通的數組有什么區別呢,普通的數組只有當參數個數不少於2個時,才會返回由參數組成的新數組。參數個數只有一個時,實際上是指定數組的長度。
下面是普通的數組,可以看看參數只有一個的區別:
var a=Array(3,9,10); var b=Array(3); console.log(a); //[3, 9, 10] console.log(b); //[,,,] console.log(b.length); //3
3、find()和findIndex()
數組實例的find方法,用於找出第一個符合條件的數組成員, 它的參數是一個回調函數,所有數組成員依次執行該回調函數,直到找出第一個返回值為true的成員,然后返回該成員。如果沒有符合條件的成員,則返回undefined。
var array=[3, 9, 10,15,6,20];
// find
var fn=array.find(function(value,index,arr){
return value>10;
});
console.log(fn); //15 當找到這個值的時候,就會停止繼續查找
var fn2=array.find(function(value,index,arr){
return value>30;
});
console.log(fn2); //undefined
// -----------------------------------------------------------------
// findIndex
var fn3=array.findIndex(function(value,index,arr){
return value>10;
});
console.log(fn3); //3
var fn4=array.findIndex(function(value,index,arr){
return value>30;
});
console.log(fn4); //-1
4、fill()
var array=['a','b','c']; array.fill(7); console.log(array); //[7, 7, 7] var array2=['a','b','c','d','e']; array2.fill(7,1,3); //在下標為 1和2的位置插入7 console.log(array2); //["a", 7, 7, "d", "e"]
有誤之處,歡迎指出
