這是一篇《數據結構與算法javascript描述》的讀書筆記。主要梳理了關於數組的知識。部分內容及源碼來自原作。
書中第一章介紹了如何配置javascript運行環境:javascript shell,不過我本人習慣使用sublime,所以直接在sublime中運行的。關於如何在sublime中配置環境請參考:
https://my.oschina.net/ximidao/blog/413101#comment-list
強烈建議把所有的代碼都擼一遍以上。

1.1 Javascript中對數組的定義
數組的標准定義:一個存儲元素的線性集合,元素可以通過索引來任意存取,索引通常是數字,用來計算元素之間存儲位置的偏移量。
不過javascript中的數組是一種特殊的對象,用來表示偏移量的索引是該對象的屬性,索引可能是整數。however,這些數字索引在內部被轉換為字符串類型,是因為javascript對象中的屬性名必須是字符串。
2.2 使用數組
2.2.1 創建數組
- var nums = [1,2,3,4]; || 該方法效率更高
- var nums = new Array(1,2,3,4);
2.2.2 讀寫數組
在一條賦值語句中,使用 [] 操作符將數據賦給數組,比如下面的循環,將1~100的數字賦給一個數組:
var nums = [];
for (var i =0; i<100;i++){
nums[i] = i+1;
}
還可以用 [ ] 操作符讀取數組中的元素:
var nums = [1,2,3,4];
var sum = nums[0]+nums[1]+nums[2]+nums[3];
console.log(sum)
2.2.3 由字符串生成數組
var sentence = "the quick brown fox jumped over the lazy dog";
var words = sentence.split(" ");
for (var i=0; i<words.length;i++){
console.log("word " + i + ":" +words[i]);
}
在上述程序中,調用 splite()方法,通過單詞之間的空格分隔符,講一句話分成及部分,並將每部分作為一個元素保存於一個新建的數組中。
2.2.4 對數組整體性的操作
1.將一個數組賦值給另外一個數組
var nums = [];
for (var i = 0; i<10;i++){
nums[i] = i+1;
}
var samenums = nums;
但是如上賦值操作,只是為被賦值的數組增加一個新的引用。當通過原引用修改了數組的值,另一個引用也會發生變化。
var nums = [];
for (var i = 0; i<10;i++){
nums[i] = i+1;
}
var samenums = nums;
nums[0] = 400;
console.log(samenums[0]); //顯示400
這種行為是淺復制,新數組依然指向原來的數組。
更好的方案是深復制,將原數組中的每一個元素都復制一份到新數組中。
//寫個深復制函數
function copy(arr1,arr2){
for (var i = 0;i<arr1.length;i++){
arr2[i] = arr1[i];
}
}
var nums = [];
for (var i = 0; i<10;i++){
nums[i] = i+1;
}
var samenums = [];
copy(nums,samenums);
nums[0] = 400;
console.log(samenums[0]); //顯示1
2.3 存取函數
2.3.1 查找元素 =====indexOf()
用來查找傳進來的參數在目標數組中是否存在。如果目標數組包含該參數,就返回元素在數組中的索引;如果不包含,就返回-1。
2.3.2 數組的字符串表示 ===== join() 和 toString()
這兩個方法都返回一個包含數組所有元素的字符串,各個元素之間用逗號分隔開。
2.3.3 由已有數組創建新數組 =====concat() 和 splice()
concat()方法可以合並多個數組創建一個新數組。
splice()方法截取一個數組的子集創建一個新數組。該方法第一個參數是截取的起始索引,第二個參數是截取的長度。
var itDiv = ["Mike","Clayton","Terrill","Raymond","Cynthia","Danny","Jennifer"];
var dmpDept = itDiv.splice(3,3); // Raymond,Cynthia,Danny print(cisDept);
var cisDept = itDiv;
console.log(dmpDept);// Mike,Clayton,Terrill,Jennifer
2.4 可變函數
2.4.1 為數組添加元素======push()和unshift()
push()方法將一個元素添加到數組末尾。
unshift()方法可以將元素添加到數組的開頭。
var nums = [2,3,4,5];
console.log(nums); // 2,3,4,5
var newnum = 1;
nums.unshift(newnum);
console.log(nums); // 1,2,3,4,5
nums = [3,4,5];
nums.unshift(newnum,1,2);
console.log(nums); // 1,2,3,4,5
2.4.2 從數組中刪除元素 pop()和 shift()
pop()方法可以刪除數組末尾的元素。
var nums = [1,2,3,4,5,9];
nums.pop();
console.log(nums); // 1,2,3,4,5
shift()方法可以刪除數組第一個元素。
var nums = [9,1,2,3,4,5];
nums.shift();
console.log(nums); // 1,2,3,4,5
pop() 和 shift() 方法都將刪掉的元素作為方法的 返回值返回,因此可以使用一個變量來保存刪除的元素:
var nums = [6,1,2,3,4,5];
var first = nums.shift(); // first gets the value 9
nums.push(first);
console.log(nums); // 1,2,3,4,5,6
2.4.3 從數組中間位置添加和刪除元素=====splice()
用splice()方法為數組添加元素,需提供如下參數:
- 起始索引(就是希望開始添加元素的地方)
- 需要刪除的元素個數(添加元素時該參數設為0)
- 想要添加進數組的元素
such as:
var nums=[1,2,3,7,8,9];
var newElements = [4,5,6];
nums.splice(3,0,newElements);
console.log(nums); //1,2,3,4,5,6,7,8,9
下面是用splice()刪除數組元素的例子:
var nums = [1,2,3,100,200,4,5];
nums.splice(3,2);
console.log(nums); //1,2,3,4,5
2.4.4 為數組排序
1.reverse() ====> 將數組中元素的順序進行翻轉
2.sort() ======>對字符型的元素按字典順序進行排序
對於數字類型的元素,如果要用sort()排序,可以在調用方法時傳入一個大小比較函數,排序時,sort()方法會根據該函數比較數組中兩個元素的大小,來決定整個數組的順序。
function compare(num1,num2){
return num1-num2;
}
var nums = [3,4,1,80,27];
nums.sort(compare);
sort()使用了compare()函數對數組按照數字大小進行排序,而不是按照字典順序。
2.5 迭代器方法
2.5.1 不生成新數組的迭代器方法
1.forEach()
接受一個函數作為參數,並對數組中的每個元素使用該函數。
function square(num){
console.log(num,num*num);
}
var nums = [1,2,3,4,5,6];
nums.forEach(square);
2.every()
接受一個返回值為布爾型的函數,對數組中的每個元素使用該函數。如果對於所有的元素,該函數都返回true,則該方法返回true。
function isEven(num){
return num%2 == 0;
}
var nums = [2,4,6,8];
var even = nums.every(isEven);
if(even){
console.log("all numbers are even");
}else{
console.log("not all numbers are even");
}
可以改改數組里的元素試試。
3.some()
some() 方法也接受一個返回值為布爾類型的函數,只要有一個元素使得該函數返回 true, 該方法就返回 true.
function isEven(num) {
return num % 2 == 0;
}
var nums = [1,2,3,4,5,6,7,8,9,10];
var someEven = nums.some(isEven);
if (someEven) {
console.log("some numbers are even");
} else {
console.log("no numbers are even");
}
nums = [1,3,5,7,9];
someEven = nums.some(isEven);
if (someEven) {
console.log("some numbers are even");
} else {
console.log("no numbers are even");
}
4.reduce()
接受一個函數,返回一個值。該方法會從一個累加值開始,不斷對累加值和 數組中的后續元素調用該函數,直到數組中的最后一個元素,最后返回得到的累加值。
下 面這個例子展示了如何使用 reduce() 方法為數組中的元素求和:
function add(runningTotal,currentValue){
return runningTotal + currentValue;
}
var nums = [1,2,3,4,5,6];
var sum = nums.reduce(add);
console.log(sum);
reduce() 方法和 add() 函數一起,從左到右,依次對數組中的元素求和。
reduce() 方法也可以用來將數組中的元素連接成一個長的字符串:
function concat(accumulatedString,tiem){
return accumulatedString + item;
}
var words = ["the ", "quick ","brown ", "fox "];
var sentence = words.reduce(concat);
console.log(sentence);
2.5.2 生成新數組的迭代器方法
1. map()
map() 和 forEach() 有點兒像,對 數組中的每個元素使用某個函數。兩者的區別是 map() 返回一個新的數組,該數組的元素 是對原有元素應用某個函數得到的結果。
function curve(grade){
return grade += 5;
}
var grades = [78,89,92,74];
var newgrades = grades.map(curve);
console.log(newgrades); // 83,94,97,79
2. filter()
filter() 和 every() 類似,傳入一個返回值為布爾類型的函數。和 every() 方法不同的是, 當對數組中的所有元素應用該函數,結果均為 true 時,該方法並不返回 true,而是返回 一個新數組,該數組包含應用該函數后結果為 true 的元素。
function passing(num) {
return num >= 60;
}
var grades = [];
for (var i = 0; i < 20; ++i) {
grades[i] = Math.floor(Math.random() * 101);
}
var passGrades = grades.filter(passing);
console.log("All grades: ");
console.log(grades);
console.log("Passing grades: ");
console.log(passGrades);
