javascript数据结构跟算法 第二章 (数组)
数组是计算机编程中最为常见的数据结构.每一种编程语言都包括某种形式的数组.因为它们是内置的所以它们非常高效,往往被用来作为存储数据的选择.
这一章,我们将会研究数组在javascript中是如何工作的.
javascript数组定义
标准的数组定义是一个线性元素的集合.我们可以通过数组的下标来获取数组的内容.下标通常是被用来计算偏移量的整数.javascript也有这样的数组,另一方面,它同时有一种不同类型的数组.
javascript数组是一种特殊类型的javascript对象.下标属性可以使用整形名字来代表偏移量.然而,当整形被用来当做下标时,它们会在内部将整形转化为字符串型来统一javascript对象的需求.因为javascript数组是对象,所以它们并不像其他编程语言的数组那样高效.
因为javascript数组,严格来说是javascript对象是内置在javascript语言的对象.Array 就是javascript对象公认的对象类型.正如此,你可以使用数组一系列的属性和方法.
使用数组
javascript数组的伸缩性特别强.你可以使用不同方式来创建数组,获取数组元素,查询,排序数组中的元素.javascript1.5 同时包括可以让程序员使用的数组函数.我们将会在接下来的章节中演示这样的技术.
创建数组
创建数组最简单的方法就是使用[ ]操作符来声明一个数组变量:
var number = [];
当你以这种形式创建数组的时候,该数组的长度是0.
你可以通过数组的内置length属性来验证这一点.
print(number.length);//打印0
另一种创建数组的方式是在声明一个数组变量是在[ ]操作符中带上一系列元素:
var numbers = [1,2,3,4,5];
print(numbers.length); // 打印5
你也调用Array的构造函数来创建数组
var numbers = new Array();
print(numbers.length); // 打印0
你可以调用Array构造函数来创建数组,同时传递一个变量来指定数组的长度
var numbers = new Array(10);
print(numbers.length); // 打印10
和其他编程语言不同,但是却和大多数脚本语言类似,javascript数组元素并不要求是相同类型.
var objects = [1, "Joe", true, null];
我们可以通过调用 Array.isArray()函数来验证一个对象是否是数组:
var numbers = 3;
var arr = [7,4,1776];
print(Array.isArray(number)); // 打印false
print(Array.isArray(arr)); // 打印true
我们已经介绍过了创建数组的技巧.至于哪个方法是最好的,大多数javascript专家建议使用[ ]操作符,因为它比调用Array的构造函数要更加高效.
获取和打印数组变量.
数据是用赋值语句使用[ ]操作符来指定的.
举个例子,下面的for循环将1-100的整数赋值给数组.
var nums = [];
for (var i = 0; i < 100; ++i) {
nums[i] = i+1;
}
数组元素同样是通过[ ]操作符来获取的.
var numbers = [1,2,3,4,5];
var sum = numbers[0] + numbers[1] + numbers[2] + numbers[3]
+ numbers[4];
print(sum); // 打印 15
当然,顺序的获取数组的元素还是使用for循环更加简单.
注意一点,使用for循环的时候,循环的次数使用length属性而不是一个字面上的整形变量.因为javascript数组是一个对象,它们可以超过数组创建时指定的长度,通过使用length属性,它会返回数组当前的长度,这样你就能确保你的循环进程能够获取到数组的所有元素.
从字符串创建数组
数组可以通过使用在字符串中调用split()函数的结果来创建.这个函数可以通过类似于空格这样常见的分割符来切割字符串,创建一个包含字符串中每个单元的数组.
下面的小程序演示如何使用split()函数来切割一个简单的字符串.
var sentence = "the quick brown fox jumped over the lazy dog";
var words = sentence.split(" ");
for (var i = 0; i < words.length; ++i) {
print("word " + i + ": " + words[i]);
}
程序输出的结果是:
word 0: the
word 1: quick
word 2: brown
word 3: fox
word 4: jumped
word 5: over
word 6: the
word 7: lazy
word 8: dog
聚合数组操作
你可以在数组上使用一些聚合操作.首先,你可以将一个数组赋值给另外一个数组.
var nums = [];
for (var i = 0; i < 10; ++i) {
nums[i] = i+1;
}
var samenums = nums;
然而,当你将一个数组赋值给另外一个数组时,其实是将一个数组的引用赋值给另外一个数组.当你对原始的数组做一些修改的时候,这些修改也会影响到另外一个数组.下面的代码片段演示这是怎么工作的:
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;
}
var samenums = [];
copy(nums, samenums);
nums[0] = 400;
print(samenums[0]); // 打印1
另一个你可以使用的聚合操作是使用print()来打印数组中的内容.
例如:
var nums = [1,2,3,4,5];
print(nums);
1,2,3,4,5
这样的结果可能并不非常有用.但是当你想要简单的一个数组列表时,你可以它来
展现你数组中的所有内容.
存取函数
javascript提供了一系列获取数组元素的函数.这些函数被称为存取函数,返回能代表目标数组的内容.
查询值
一个最常用的存取函数indexOf(),它用来查看传递给函数的参数是否在数组中被找到.如果数组包含该参数,函数返回该参数在数组中的下标值.如果参数值没有在数组中找到,函数返回-1.
var names = ["David", "Cynthia", "Raymond", "Clayton", "Jennifer"];
putstr("Enter a name to search for: ");
var name = readline();
var position = names.indexOf(name);
if (position >= 0) {
print("Found " + name + " at position " + position);
} else {
print(name + " not found in array.");
}
如果你允许程序,并且输入Cynthia,程序将会返回:
Found Cynthia at position 1
如果你输入的是Joe,程序将会输出:
Joe not found in array.
如果你的数组中多次出现相同的内容,indexOf()函数将会返回第一次出现该参数的下标.一个相似的函数lastIndexOf(),将会返回参数在数组中最后一次出现的下标.如果在数组中没有找到该元素,则返回-1.
var names = ["David", "Mike", "Cynthia", "Raymond", "Clayton", "Mike", "Jennifer"];
var name = "Mike";
var firstPos = names.indexOf(name);
print("First found " + name + " at position " + firstPos);
var lastPos = names.lastIndexOf(name);
print("Last found " + name + " at position " + lastPos);