數據結構與算法(刺猬書)讀書筆記(1)----數組
在JavaScript中,數組其實是一種特殊的對象,用來表示偏移量的索引是該對象的屬性,所以JavaScript的數組本質上是對象。同時這些數字索引在內部會被轉換成為字符串類型,因為JavaScript對象中的屬性名必須是字符串。此外,JavaScript數組還有一個特點,就是數組的每一項可以保存任何類型的數據,而且,數組的大小是可以動態調整的。
1. 創建數組
數組的創建方法有兩種,第一種是簡單的聲明一個數組變量:
var numbers = []; var numbers = [1, 2, 3, 4, 5]
由於數組就是一種特殊的對象,所以第三種是調用Array的構造函數創建數組。
varnumbers = new Array(); var numbers = new Array(1, 2, 3, 4, 5);
這兩種方法對比起來,使用[]操作符來聲明數組變量被認為效率更高,所以推薦使用這種方法。
2. 對數組的整體性操作
數組的復制分為潛伏之和深復制兩種。由於數組是特殊的對象,所以將數組賦值給一個變量的時候,賦值過去的只是這個數組的引用。如果通過原因用修改了數組的值,所有引用了這個數組的變量都相當於被修改成了新的值。所以在復制數組的時候,更好的方法是深復制,創建一個新數組,將現有數組中的每一個元素都復制到新數組去,這樣就實現了完全的復制。
淺復制:
var nums = [];for (var i = 0; i < 100; ++i) { nums[i] = i + 1; } var samenums = nums; nums[0] = 400; print(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 < 100; ++i) { nums[i] = i + 1; } varsamenums = []; copy(nums, samenums); nums[0] = 400; print(samenums[0]); // 1
3. 數組相關的方法
3.1 由字符串生成數組
調用字符串對象的split()方法可以生成數組,在方法中傳遞分隔符,然後字符串將根據分隔符進行分割形成數組。
3.2 查找數組
indexOf():返回第一個與參數相同的元素的索引。
lastIndexOf():返回相同元素中最後一個元素的索引。
如果沒找到相同元素則返回-1。
這裏有一個查找方法基本的寫法,就是如果沒找到的話一般都會返回-1,而不是其他亂七八糟的東西。
3.3 數組的字符串表示
有兩個方法可將數組轉化為字符串:join() 和 toString()。除此之外,直接對一個數組使用print()函數時,系統會自動調用那個數組的toString()方法。
3.4 合並多個數組
concat()函數可以合並多個數組創建一個新數組。該方法的發起者是一個數組,參數是另一個數組。參數中所有元素都被連接到調用concat()方法的數組後面。
3.5 在數組中添加刪除元素
添加元素:push() 和 unshift()
刪除元素:pop() 和 shift()
萬能方法:splice()
註意:這些方法都是直接對原數組進行操作的。
push()可將一個元素添加到數組末尾,unshift()可將元素添加在數組的開頭。pop()可刪除數組末尾的元素,shift()可刪除數組第一個元素。
splice方法中可以提供三個參數:1. 起始索引
2. 需要刪除的元素個數
3. 想要添加進數組的元素
通過合理的運用這三個參數即可實現添加或者刪除元素。同時,splice()函數會返回刪除掉的元素組成的數組,所以也可被用來從現有數組裏截取一個新數組。但需要註意的是,該方法會修改原數組,所以用作截取數組時應該考慮是否希望原數組改變。
下面提供splice()三種用法的示例
添加元素:
var nums = [1, 2, 3, 7, 8, 9]; var newElements = [4, 5, 6]; nums.splice(3, 0, newElements); print(nums); // [1, 2, 3, [4, 5, 6], 7, 8, 9]
註意:這裏傳進去的希望添加進數組的元素如果是個數組,整個數組將會被看做一個元素被添加進數組,而不是將數組中的元素添加進數組。
如想要插入多個元素可以這樣寫:
var nums = [1, 2, 3, 7, 8, 9]; nums.splice(3, 0, 4, 5, 6); print(nums); // [1, 2, 3, 4, 5, 6, 7, 8, 9];
刪除元素:
var nums = [1, 2, 3, 100, 200, 300, 400, 4, 5]; nums.splice(3, 4); print(nums); // 1,2,3,4,5
截取數組:
var num = [1, 2, 3, 4, 5, 6, 7, 8]; var someNum = num.splice(3, 3); var remainNum = num; print(someNum); // 4,5,6 print(remainNum); // 1,2,3,7,8
3.6 為數組排序
有兩個排序相關算法:reverse() 和 sort()。reverse()可將數組中元素的順序進行翻轉。sort()允許傳入比較函數,並對數組進行排序。
當sort()函數中沒有傳入任何參數時,無論是字符串還是數字,都是按照字典順序對元素進行排序的:
var names = ["David", "Mike", "Cynthia", "Clayton", "Bryan", "Raymond"]; names.sort(); print(names); // Bryan,Clayton,Cynthia,David,Mike,Raymond var nums = [3, 1, 2, 100, 4, 200]; nums.sort(); print(nums); // 1,100,2,200,3,4
如果想要按照數字大小進行排序,可以傳入一個比大小函數:
function compare(num1, num2) { return num1 - num2; } var nums = [3, 1, 2, 100, 4, 200]; nums.sort(compare); print(nums); // 1,2,3,4,100,200
傳入的函數應該返回一個正值或負值,如果是正值則第一個參數位於第二個參數前邊,反之則第二個參數在前面。
3.7 叠代器方法
3.7.1 不生成新數組的叠代器方法
foreach():接受一個函數作為參數,對數組中的每個元素使用該函數。
every():接受一個返回值為布爾類型的函數,對數組中的每個元素使用該函數。如果所有的元素都使得該函數返回true,該函數返回true。
some():接受一個返回值為布爾類型的函數,只要有一個元素使得該函數返回true,該方法就返回true。
reduce():接受一個函數,返回一個值。該方法會從一個累加值開始,不斷對累加值和數組中的後續元素調用該函數,直到數組中的最後一個元素,最後返回得到的累加值。reduce()接受的函數接受兩個參數,第一個參數是到目前為止累加出來的值,第二個參數時現在的值。
reduceRight():從右到左執行。
3.7.2 生成新數組的叠代器方法
map():接受一個函數作為參數,返回一個新的數組,該數組的元素是對原有元素應用那個函數得到的結果。
filter():接受一個函數作為參數,返回所有能使該函數返回true的元素。
4. 二維和多維數組
JavaScript中沒有二維數組,但可以通過在數組中插入數組元素來實現二維數組。
var twod = []; var rows = 5; for (var i = 0; i < rows; ++i) { twod[i] = []; }
關於如何創建二維數組,書中提到了一個最佳實踐,是JavaScript: The Good Parts (O‘Reilly)一書中64頁的例子。
Array.matrix = function(numrows, numcols, initial) { var arr = []; for (var i = 0; i < numrows; ++i) { // 設置行 var columns = []; for (var j = 0; j < numcols; ++j) { // 設置列 columns[j] = initial; } arr[i] = columns; } return arr; }
這樣就形成了一個numrows行,numcols列的二維數組,可以通過arr[i][j]訪問到其中的每一個元素。
如果要對二維數組中的元素進行處理,也可通過這種嵌套循環的方式來訪問到每個元素並對每個元素進行操作,此處要註意循環參數最好參照arr.length進行循環,這樣即使是參差不齊的數組也可以很好的進行處理。
5. 對象與數組
數組中也可包含對象,對象中也可包含數組,這使得數組的應用更加廣闊。
數據結構與算法(刺猬書)讀書筆記(1)----數組