数据结构之数组

数组

  1. 几乎所有的编程语言都原生支持数组类型,因为数组是最简单的内存数据结构。
  1. 数组存储一系列同一种数据类型的值。但在JavaScript里,也可以在数组中保存不同类型的值。
  1. JavaScript 中的数组,严格来说应该称作对象,是特殊的 JavaScript 对象,在内部被归类为数组。
    由于 Array 在 JavaScript 中被当作对象,因此它有许多属性和方法可以在编程时使用。
  1. 数组的标准定义是:一个存储元素的线性集合(collection),元素可以通过索引来任意存取,索引通常是数字,用来计算元素之间存储位置的偏移量。

创建数组

1. 通过[] 操作符声明一个数组变量

var array = []

array[0] = 1
array[1] = 2
...
  1. 在声明数组变量时,直接在 [] 操作符内放入一组元素
var array = [1, 2, 3, 4, 5]
  1. 可以调用 Array 的构造函数创建数组
var array = new Array()

var array = new Array(1, 3, 5, 7, 9)
  1. 在调用 Array 的构造函数时,可以只传入一个参数,用来指定数组的长度
var array = new Array(10)
array.length = 10
  1. 在脚本语言里很常见的一个特性是,数组中的元素不必是同一种数据类型,这一点和很多
    编程语言不同
var objects = [1, "Joe", true, null]
  1. 调用 Array.isArray() 来判断一个对象是否是数组
var arr = [1, 5, 9]
Array.isArray(arr)

使用数组

  • 读写数组
  1. 在一条赋值语句中,可以使用 [] 操作符将数据赋给数组
var nums = []
for (var i = 0; i < 100; i++ ) {
  nums[i] = i + 1
}
  1. 以使用 [] 操作符读取数组中的元素
var numbers = [1,2,3,4,5];
var sum = numbers[0] + numbers[1] + numbers[2] + numbers[3] + numbers[4];
  • 由字符串生成数组
  1. 字符串对象的 split()方法也可以生成数组
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]);
}

存取函数

JavaScript 提供了一组用来访问数组元素的函数,叫做存取函数,这些函数返回目标数组的某种变体。

  1. 查找元素
  • indexOf() 函数用来查找传进来的参数在目标数组中是否存在。如果目标数组包含该参数,就返回该元素在数组中的索引;如果不包含,就返回 -1
  • lastIndexOf()该函数返回相同元素中最后一个元素的索引,如果没找到相同元素,则返回 -1
var array = [1, 3, 5, 7, 7, 9]
array.indexOf(1)  // 0
array.indexOf(5)  // 2
array.indexOf(2)  // -1

array.indexOf(7)  // 3
array.lastIndexOf(7)  // 4

// 数组去重
var arr = [1,2,2,3,4,5,5,6,7,8,7]
var newArr = []
for(var i = 0; i< arr.length; i++) {
  if (newArr.indexOf(arr[i]) < 0) {
    newArr.push(arr[i])
  }
}
console.log(newArr)  // [1, 2, 3, 4, 5, 6, 7, 8]
  1. 数组的字符串表示
  • 有两个方法可以将数组转化为字符串: join() 和 toString() 。这两个方法都返回一个包含
    数组所有元素的字符串,各元素之间用逗号分隔开
var names = ["David", "Cynthia", "Raymond", "Clayton", "Mike", "Jennifer"]
console.log(names.join())  // "David,Cynthia,Raymond,Clayton,Mike,Jennifer"
console.log(names.toString())  // "David,Cynthia,Raymond,Clayton,Mike,Jennifer"
  1. 由已有数组创建新数组
  • concat() 和 splice() 方法允许通过已有数组创建新数组。 concat方法可以合并多个数组
    创建一个新数组, splice() 方法截取一个数组的子集创建一个新数组。
  • concat() 方法的工作原理: 该方法的发起者是一个数组,参数是另一个数组
  • splice() 方法从现有数组里截取一个新数组, 该方法的第一个参数是截取的起始索引,第二个参数是截取的长度, 第三个参数可选, 数组中添加新项目
var a = [1, 2, 5]
var b = [6, 9, 3]
console.log(a.concat(b))  // [1, 2, 5, 6, 9, 3]

var a = [1, 2, 5, 6, 9, 3]
console.log(a.splice(2,2))  // [5, 6]
console.log(a)  // [1, 2, 9, 3]

console.log(a.splice(2, 2, 12, 13, 15))
console.log(a)  // [1, 2, 12, 13, 15, 9, 3]

可变函数

  1. 为数组添加元素
  • push() 方法会将一个元素添加到数组末尾
  • unshift() 方法可以将元素添加在数组的开头
var a = [1, 2, 3, 4]
a.push(6)
a.push(11, 13)
a  // [1, 2, 3, 4, 6]
a  // [1, 2, 3, 4, 6, 11, 13]
a.unshift(8)
a  // [8, 1, 2, 3, 4, 6]
  1. 从数组中删除元素
  • pop() 方法可以删除数组末尾的元素
  • shift() 方法可以删除数组的第一个元素
  • pop()shift() 方法都将删掉的元素作为方法的返回值返回,因此可以使用一个变量来保存删除的元素
var b = [1, 3, 5, 7, 9]
b.pop()
b  // [1, 3, 5, 7]

b.shift()
b  // [3, 5, 7]
  1. 从数组中间位置添加和删除元素
  • splice() 方法为数组添加元素
    • 起始索引(也就是你希望开始添加元素的地方);
    • 需要删除的元素个数(添加元素时该参数设为 0);
    • 想要添加进数组的元素。
var nums = [1,2,3,7,8,9]
nums.splice(3, 0, 4, 5, 6)
nums  //  [1, 2, 3, 4, 5, 6, 7, 8, 9]
  1. 为数组排序
  • reverse() ,该方法将数组中元素的顺序进行翻转
var nums = [1, 2, 3, 4, 5]
nums.reverse()
nums  // [5, 4, 3, 2, 1]
  • sort() 方法是按照字典顺序对元素进行排序的,因此它假定元素都是字符串类型
var names = ["David", "Mike", "Cynthia", "Clayton", "Bryan", "Raymond"]
names.sort()  // ["Bryan", "Clayton", "Cynthia", "David", "Mike", "Raymond"]

var nums = [3, 1, 2, 100, 4, 200]
nums.sort()  // [1, 100, 2, 200, 3, 4]

function compare(num1, num2) {
  return num1 - num2;
}
var nums = [3,1,2,100,4,200];
nums.sort(compare);  // [1, 2, 3, 4, 100, 200]

迭代器方法

  1. 不生成新数组的迭代器方法
  • forEach()该方法接受一个函数作为参数
var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
nums.forEach( (item, index, array) => {
   console.log(item * 2)  // 2, 4, 6, 8 ...
})
  • every() 该方法接受一个返回值为布尔类型的函数,对数组中的每个元素使用该函数。如果对于所有的元素,该函数均返回 true ,则该方法返回 true
    • every() 不会对空数组进行检测。
// item 必须。当前元素的值
// index 可选。当前元素的索引值
// array 可选。当前元素属于的数组对象
var ages = [32, 33, 16, 40]
ages.every((item, index, array) => {
  return item >= 18  // false
})
  • some() 方法也接受一个返回值为布尔类型的函数,只要有一个元素使得该函数返回true,
    该方法就返回 true
// item 必须。当前元素的值
// index 可选。当前元素的索引值
// array 可选。当前元素属于的数组对象
var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
nums.some((item, index, array) => {
    return item % 2 == 0
})
  • reduce() 方法接受一个函数,返回一个值。该方法会从一个累加值开始,不断对累加值和
    数组中的后续元素调用该函数,直到数组中的最后一个元素,最后返回得到的累加值
语法: 
arr.reduce(callback[, initialValue])

accumulator 累计器
currentValue 当前值
currentIndex 当前索引
array 数组

callback
  执行数组中每个值的函数,包含四个参数:
  accumulator :累计器累计回调的返回值; 它是上一次调用回调时返回的累积值或initialValue
  currentValue :数组中正在处理的元素
  currentIndex : 可选 | 数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则为1。
  array : 可选 | 调用reduce()的数组

initialValue : 可选 | 作为第一次调用 callback函数时的第一个参数的值。 
如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
 
var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
nums.reduce((accumulator, currentValue, currentIndex, array) => {
  // Todo
}, initialValue)

nums.reduce((accumulator, currentValue, currentIndex, array) => {
  return accumulator + currentValue  // 55
}, 0)

nums.reduce((accumulator, currentValue, currentIndex, array) => {
  return accumulator + currentValue  // 65
}, 10)
  1. 生成新数组的迭代器方法
  • map() 返回一个新的数组,该数组的元素是对原有元素应用某个函数得到的结果
// item 必须。当前元素的值
// index 可选。当前元素的索引值
// array 可选。当前元素属于的数组对象

var grades = [77, 65, 81, 92, 83]
grades.map((item, index, array) => {
    return item + 5  // [82, 70, 86, 97, 88]
})
grades  // [77, 65, 81, 92, 83]
  • filter()every() 类似,传入一个返回值为布尔类型的函数。和 every() 方法不同的是,
    当对数组中的所有元素应用该函数,结果均为 true 时,该方法并不返回 true ,而是返回 一个新数组,该数组包含应用该函数后结果为 true 的元素
// item 必须。当前元素的值
// index 可选。当前元素的索引值
// array 可选。当前元素属于的数组对象

var num = [1, 2, 3, 4, 5, 6, 7, 8]
num.filter((item, index, array) => {
  return item % 2 == 0  // [2, 4, 6, 8]
})
num  // [1, 2, 3, 4, 5, 6, 7, 8]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352