javascript數據結構與算法之數組

數組的定義

數組是一個線性分配的內存, 存儲的元素能夠經過索引(一般爲數字)來任意存取,而這個索引(也就是咱們所謂的下標,從0開始)用來計算元素之間存儲的位置的偏移量(其實就是爲了區分不一樣的數據)。javascript

js的數組和其它編程語言有些不一樣,表面上看和大多編程語言的數組差很少,但在內部卻有着不同的實現。js提供了一些類數組(array-like)特性的對象。它會把數組的下標轉變成字符串,變成一個對象的屬性。好比java

var numbers = ['zero', 'one', 'two'];

這個簡單的數組會被轉換爲編程

var numbers_object = {'0': 'zero', '1': 'one', '2': 'two'};

從代碼自己的功能來講沒有太大區別,恰好有相同的名字和值。可是numbers繼承了Array.prototype,而numbers_object繼承了Object.prototype。因此numbers就有了大量有用好玩的方法,還有一個特別的length屬性。數組

js數組還有的一個特別之處是數組能夠包含任何類型的數據,混合型的,很強大。編程語言

特別的length屬性

  1. 每一個數組都有一個length屬性,length是沒有上界的。若是用大於等於數組長度的數字做爲下標來存儲元素,那麼length的值就會增大來容納新元素,不會發生數組越界。函數

    var array = [10];
    var array[11] = 'iCoding';
    array.length //12prototype

  2. 那麼問題來了,js數組有沒有下界。通常狀況下數組都是從0開始的,若是執行array[-1] = 'net'會發生什麼狀況呢?數組的長度length會怎樣變化?抱着刨根問題的精神回答,js數組會給array增長屬性爲-1的 '-1': 'net' 元素 ,其實本質就是上面所說的轉換成對象,此時咱們查詢length的值並未發生變化,估計js源代碼的length屬性的值是從0開始計數的。code

建立數組

  1. 最簡單的方式對象

    var numbers = [ ]; //length = 0繼承

  2. 直接放入一組元素

    var numbers = [1,2,3]; //length = 3

  3. 經過構造函數建立數組

    var numbers = new Array(); //length = 0

  4. 一樣能夠直接放入一組元素

    var numbers = new Array(1,2,3); //length = 3

那麼那種方式最好?大多數javascript專家推薦使用[ ] 操做符,和使用構造函數相比,這種方式被認爲效率最高。

數組操做

array[array.length] = 'iCoding';   --> ['zero', 'one', 'two', 'iCoding']

array.push('net');  --> ['zero', 'one', 'two', 'iCoding', 'net']

  1. 因爲JavaScript的數組其實就是對象,因此delete運算符能夠用來從數組中移除元素

    delete array[1]; --> ['zero', , 'two', 'iCoding', 'net']

可是這種方式會在數組中留下一空洞。由於排在後面的元素還會保留着它們最初的屬性。

  1. JavaScript中有一個splice方法

    var array = ['zero', 'one', 'two', 'iCoding', 'net']

    array.splice(1, 1); -->['zero', 'two', 'iCoding', 'net']

其中splice第一個參數表示移除的位置,第二個參數表示移除元素的個數。

可是很差的一點是:被刪除屬性後面的每個屬性必須被移除,而且以一個新的鍵值從新插入,若是操做大型數組,效率可能就會不高。

  1. 若是想修改數組,依然能夠用splice方法

    var array = ['a', 'b', 'c', 'd', 'e'];

    array.splice(3, 1, 'icoding', 'net'); -->['a', 'b', 'c', 'icoding', 'net', 'e'];

對數組的總體性操做

  1. 淺複製

當咱們將一個數組賦給另一個數組,只是爲被賦值的數組增長了一個新的引用。當你經過原引用修改了數組的值,另外一個引用也會感知到這個變化,相應的值就會發生改變。這種行爲被稱爲淺複製。

var nums = [0, 1, 2, 3];
var same_nums = nums;
nums[1] = 99;
console.log(same_nums[1]); //99
  1. 深複製

顧名思義,也就是咱們不一樣經過引用來改變另外一個本身。寫個函數就ok了。

function copy(arr1, arr2) {
for(var i = 0, i < arr1.length, i++) { 
arr2[i] = arr1[i]; 
  }
}

將每一個數組中的值遍歷出來在從新賦值到新數組中,在咱們程序中調用一下就行了。

var nums = [0, 1, 2, 3];
var same_nums = []
copy(nums, same_nums);
nums[1] = 99;
console.log(same_nums[1]); //1

數組轉化成字符串

這裏有join()和toString()兩個方法。

var names = ['joes', 'beyond'];

var namestr1 = names.join(); 

console.log(namestr);  //'joes,beyond'

var namestr2 = names.toString(); 

console.log(namestr);  //'joes,beyond'

由已有數組建立新數組

contact()和splice()方法容許經過已有數組建立數組。contact方法能夠合併多個數組建立一個數組,splice()方法截取一個數組的子集建立一個新數組。

咱們先來看看contact()方法的工做原理。隨意建立2個數組。

var nums1 = [1, 2, 3, 4, 5];
var nums2 = [6, 7, 8, 9];
var mix_nums = nums1.contact(nums2);
console.log(mix_nums);  // [1, 2, 3, 4, 5, 6, 7, 8, 9]

參考

Michael McMillan.《Data Structures & Algorithms with JavaScript》Douglas Crockford.《JavaScript: The Good Parts》

相關文章
相關標籤/搜索