第2章“數組”
一.爲什麼用數組
- 數組是最簡單的內存數據結構
數組存儲一系列同一種數據類型的值。但在JavaScript裏,也可以在數組中保存不同類型的值。
但我們還是要遵守最佳實踐,別這麼做(大多數語言都沒這個能力)。 - 爲什麼用數組
可以用數組來解決,更加簡潔地呈現
var averageTempJan = 31.9;
var averageTempFeb = 35.3;
var averageTempMar = 42.4;
var averageTempApr = 52;
var averageTempMay = 60.8;
使用數組:
averageTemp[0] = 31.9;
averageTemp[1] = 35.3;
averageTemp[2] = 42.4;
averageTemp[3] = 52;
averageTemp[4] = 60.8;
二.創建和初始化數組
- 創建和初始化數組
聲明聲明、創建和初始化數組
var daysOfWeek = new Array(); //簡單聲明並初始化一個數組
var daysOfWeek = new Array(7); //簡單聲明並初始化一個數組,並指定數組長度
var daysOfWeek = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'); //直接將數組元素作爲參數傳遞給它的構造器
其實,用new創建數組並不是最好的方式。如果你想在JavaScript中創建一個數組,只用中括號([])的形式就行了
var daysOfWeek = [];
也可使用一些元素初始化數組
var daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'];
console.log(daysOfWeek.length); //數組裏已經存了多少個元素,可以使用數組的length屬性
要訪問數組裏特定位置的元素,可以用中括號傳遞數值位置,得到想知道的值或者賦新的值。
假如我們想輸出數組daysOfWeek裏的所有元素,可以通過循環遍歷數組,打印元素,如下所示:
for (var i=0; i<daysOfWeek.length; i++){
console.log(daysOfWeek[i]);
}
求斐波那契數列的前20個數字。已知斐波那契數列中第一個數字是1,
第二個是2,從第三項開始,每一項都等於前兩項之和:
var fibonacci = []; //聲明並創建了一個數組
fibonacci[1] = 1; //
fibonacci[2] = 1; //把斐波那契數列中的前兩個數字分別賦給了數組的第二和第三位
for(var i = 3; i < 20; i++){
fibonacci[i] = fibonacci[i-1] + fibonacci[i-2]; //用循環來處理,把數組中前兩位上的元素相加,結果賦給當前位置上的元素
}
for(var i = 1; i<fibonacci.length; i++){ //要循環遍歷數組的各個元素
console.log(fibonacci[i]); //輸出
}
三.添加和刪除元素
- 添加一個元素,原始方法
如果想要給數組添加一個元素(比如10),
只要把值賦給數組中最後一個空位上的元素即可
var numbers=[0,1,2,3,4,5,6,7,8,9];
numbers[numbers.length]=10;
console.log('numbers:'+numbers);
- 數組的方法:push方法,能把元素添加到數組的末尾
var numbers=[0,1,2,3,4,5,6,7,8,9];
numbers.push(11);
numbers.push(12, 13);
如果輸出numbers的話,就會看到從0到13的值。
- 在JavaScript裏,數組有一個方法叫unshift,可以直接把數值插入數組的首位
var numbers=[0,1,2,3,4,5,6,7,8,9];
numbers.unshift(-2);
numbers.unshift(-4, -3);
- pop方法:刪除數組最後一個元素
numbers.pop();
- Shift方法實現:刪除數組的第一個元素
numbers.shift();
- 使用splice方法,簡單地通過指定位置/索引,就可以刪除相應位置和數量的元素
numbers.splice(5,3);
//刪除數組下標爲5之後三個(包括數組下標爲5的這個元素)
var numbers=[0,1,2,3,4,5,6,7,8,9];
snumber=numbers.splice(5,3);
console.log(snumber);//(3) [5, 6, 7]
console.log(numbers);//(7) [0, 1, 2, 3, 4, 8, 9]
想把數字2、2、4插入數組裏,放到之前刪除元素的位置上,
可以再次使用splice方法:
var numbers=[0,1,2,3,4,5,6,7,8,9];
snumber=numbers.splice(5,3);
console.log(snumber);//(3) [5, 6, 7]
console.log(numbers);//(7) [0, 1, 2, 3, 4, 8, 9]
//插入數字
addNumber=numbers.splice(5,0,2,2,4);
console.log(addNumber);//[]
console.log(numbers);//(10) [0, 1, 2, 3, 4, 2, 2, 4, 8, 9]
splice方法接收的第一個參數,表示想要刪除或插入的元素的索引值。
第二個參數是刪除元素的個數(這個例子裏,我們的目的不是刪除元素,所以傳入0)。
第三個參數往後,就是要添加到數組裏的值(元素2、3、4)。
四.二維和多維數組
- JavaScript只支持一維數組,並不支持矩陣。但是,我們可以用數組套數組,實現矩陣或任一多維數組。
//day 1
averageTemp[0] = [];
averageTemp[0][0] = 72;
averageTemp[0][1] = 75;
averageTemp[0][2] = 79;
averageTemp[0][3] = 79;
averageTemp[0][4] = 81;
averageTemp[0][5] = 81;
//day 2
averageTemp[1] = [];
averageTemp[1][0] = 81;
averageTemp[1][1] = 79;
averageTemp[1][2] = 75;
averageTemp[1][3] = 75;
averageTemp[1][4] = 73;
averageTemp[1][5] = 72;
如果想看這個矩陣的輸出,我們可以創建一個通用函數,專門輸出其中的值:
var averageTemp = [];
averageTemp[0] = [72,75,79,79,81,81];
averageTemp[1] = [81,79,75,75,73,72];
function printMatrix(myMatrix) {
for (var i=0; i<myMatrix.length; i++){
for (var j=0; j<myMatrix[i].length; j++){
console.log("("+i+","+j+")"+myMatrix[i][j]);
}
}
}
printMatrix(averageTemp);
【需要遍歷所有的行和列。
因此,我們需要使用一個嵌套的for循環來處理,其中變量i爲行,變量j爲列。
使用以下代碼查看矩陣averageTemp的輸出:
printMatrix(averageTemp); 】
以此類推,也可以用這種方式來處理多維數組。
假如我們要創建一個3×3的矩陣,每一格里
包含矩陣的i(行)、j(列)及z(深度)之和:
var matrix3x3x3 = [];
for (var i=0; i<3; i++){
matrix3x3x3[i] = [];
for (var j=0; j<3; j++){
matrix3x3x3[i][j] = [];
for (var z=0; z<3; z++){
matrix3x3x3[i][j][z] = i+j+z;
}
}
}
五.JavaScript 的數組方法參考
-
在JavaScript裏,數組是可修改的對象,這意味着創建的每個數組都有一些可用的方法。數組很有趣,因爲它們十分強大,並且相比其他語言中的數組,JavaScript中的數組有許多很好用的方法。這樣就不用再爲它開發一些基本功能了,例如在數據結構的中間添加或刪除元素。
-
數組合並,叫作concat方法
var zero = 0;
var positiveNumbers = [1,2,3];
var negativeNumbers = [-3,-2,-1];
var numbers = negativeNumbers.concat(zero, positiveNumbers);
console.log(numbers);//[-3, -2, -1, 0, 1, 2, 3] 前面+concat+後面=新的數組
concat方法可以向一個數組傳遞數組、對象或是元素。
- 迭代器函數:可以用循環語句來處理,例如for語句。還有一個方法是every。
every方法:
實現功能:假如有
一個數組,它值是從1到15,如果數組裏的元素可以被2整除(偶數),函數就返回true,否則返回false
var isEven = function (x) {
// 如果x是2的倍數,就返回true
console.log(x);
return (x % 2 == 0) ? true : false;//也可以寫成return (x % 2== 0)。
// 也可以寫成return (x % 2 == 0) ? true : false
};
var numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
newNum = numbers.every(isEven);
console.log(newNum);
var numbers1 = [2,4,6];
newNum1 = numbers1.every(isEven);
console.log(newNum1);
- 看some方法。它和every的行爲類似,不過some方法會迭代數組的每個元素,直到函數返回true
var numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
newNum = numbers.some(isEven);
console.log(newNum);
- 如果要迭代整個數組,可以用forEach方法。它和使用for循環的結果相同
var numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var newNum = numbers.forEach(function(x){
console.log((x % 2 == 0));
});
console.log(newNum);
- JavaScript還有兩個會返回新數組的遍歷方法。第一個是map:
var myMap = numbers.map(isEven);
數組myMap裏的值是:[false, true, false, true, false, true, false, true,
false, true, false, true, false, true, false]。它保存了傳入map方法的isEven函
數的運行結果。
這樣就很容易知道一個元素是否是偶數。比如,myMap[0]是false,因爲1不是
偶數;而myMap[1]是true,因爲2是偶數。
第二個是:個filter方法。它返回的新數組由使函數返回true的元素組成:
var evenNumbers = numbers.filter(isEven);
在我們的例子裏,evenNumbers數組中的元素都是偶數:[2, 4, 6, 8, 10, 12, 14]。
-------------------
var isEven = function (x) {
// 如果x是2的倍數,就返回true
console.log(x);
return (x % 2 == 0) ? true : false;//也可以寫成return (x % 2== 0)。
// 也可以寫成return (x % 2 == 0) ? true : false
};
var numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var evenNumbers = numbers.filter(isEven);
console.log(evenNumbers);//(7) [2, 4, 6, 8, 10, 12, 14]
- 是reduce方法。reduce方法接收一個函數作爲參數,這個函數有四個參數:previousValue、currentValue、index和array。這個函數會返回一個將被疊加到累加器的值,reduce方法停止執行後會返回這個累加器。
如果要對一個數組中的所有元素求和,這就很
有用,比如:
numbers.reduce(function(previous, current, index){
return previous + current;
});
——————————————————
var numbers = [1,2,6,7,8,91,12,13,14,15];
var sum = numbers.reduce(function(previous, current, index){
console.log(index+" ");
return previous + current;
});
console.log(sum);//169和
- 搜索和排序
想反序輸出數組
var numbers = [1,2,6,7,8,91,12,13,14,15];
var newSort = numbers.reverse();
console.log(newSort);
用sort方法:法在對數組做排序時,把元素默認成字符串進行相互比較。
var numbers = [1,2,6,7,8,91,12,13,14,15];
var newSort = numbers.sort();
console.log(newSort);
自定義比較函數(升序排序)
var numbers = [1,2,6,7,8,91,12,13,14,15];
function compare(a, b) {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
// a必須等於
return 0;
}
var newSort = numbers.sort(compare);
console.log(newSort);
- 自定義排序
我們可以對任何對象類型的數組排序,也可以創建compareFunction來比較元素。例如,
對象Person有名字和年齡屬性,我們希望根據年齡排序,就可以這麼寫:
var friends = [
{name: 'John', age: 30},
{name: 'Ana', age: 20},
{name: 'Chris', age: 25}
];
function comparePerson(a, b){
if (a.age < b.age){
return -1
}
if (a.age > b.age){
return 1
}
return 0;
}
console.log(friends.sort(comparePerson));
在這個例子裏,最後會輸出Ana(20), Chris(25), John(30)。
- 字符串排序
var names =['Ana', 'ana', 'john', 'John'];
console.log(names.sort());
輸出:
["Ana", "John", "ana", "john"]
是根據字符對應的ASCII值來比較的。例如,A、J、a、j對應的ASCII值分別是65、75、7、106。
雖然在字母表裏a是最靠前的,但J的ASCII值比a的小,所以排在a前面
- 例子
現在,如果給sort傳入一個忽略大小寫的比較函數,將會輸出["Ana", "ana", "John",
"john"]:
names.sort(function(a, b){
if (a.toLowerCase() < b.toLowerCase()){
return -1
}
if (a.toLowerCase() > b.toLowerCase()){
return 1
}
return 0;
});
- 搜索
搜索有兩個方法:indexOf方法返回與參數匹配的第一個元素的索引,lastIndexOf返回與參數匹配的最後一個元素的索引。
var numbers = [1,2,6,7,8,91,12,13,14,15];
console.log(numbers.indexOf(4));//-1 因爲數組元素沒有4這個數字的出現
console.log(numbers.indexOf(1));//0 是數組的第一個元素所以輸出的下標是0
console.log(numbers.indexOf(6));//2 是數組的第三個元素,數組下標是2
var numbers = [1,2,6,7,8,91,12,13,14,12];
console.log(numbers.lastIndexOf(12));//9最後一個出現12的是最後一個元素
console.log(numbers.lastIndexOf(4));//-1沒有出現
- 輸出數組爲字符串
兩個方法:toString和join。
把數組裏所有元素輸出爲一個字符串,可以用toString方法:
var numbers = [1,2,6,7,8,91,12,13,14,12];
console.log(numbers.toString());//1,2,6,7,8,91,12,13,14,12
如果想用一個不同的分隔符(比如-)把元素隔開,可以用join方法:
var numbers = [1,2,6,7,8,91,12,13,14,12];
var numbersString = numbers.join('-');
console.log(numbersString);//1-2-6-7-8-91-12-13-14-12