前言

Hello,大家好,这里是成功在家隔离四天的GIS宇宙,最近趁着不怎么忙碌,可以好好学习一下算法和数据结构了,本科期间基本学了和没学一样,所以接下来会出一个关于JavaScript算法和数据结构的专栏,本人水平有限,也是边学边记录,如果你喜欢这个专栏的话,可以点个赞,蟹蟹~

今天首先对JavaScript最基础的数组进行介绍,下一篇会介绍栈,感兴趣的赶紧关注我吧~

数组创建

  1. new 关键字
  2. 中括号
let daysOfWeek = new Array(); // {1}
daysOfWeek = new Array(7); // {2}
daysOfWeek = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); // {3}let daysOfWeek = []
let daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', ]

添加元素

1.尾部插入push

daysOfWeek.push(123)

2.头部插入unshift

头部操作,首先将 i 元素赋值给 i+1,然后在索引0的位置插入新值

daysOfWeek.unshift(-1)

如果自己写的话,则为数组右移,腾出头部位置,还多申明了一个数组位置

Array.prototype.insertFirstPosition = function(value) { for (let i = this.length; i >= 0; i--) { this[i] = this[i - 1]; } this[0] = value;
};
numbers.insertFirstPosition(-1);

删除元素

1.尾部删除

daysOfWeek.pop()

2.头部删除

daysOfWeek.shift()

将所有元素都赋值给前一个元素,并删除最后一个值,length最后变为16。

如果直接左移(如下述),最后一个元素会报错变成undefined。

for (let i = 0; i < numbers.length; i++) { numbers[i] = numbers[i + 1];
}

任意位置添加删除元素

numbers.splice(5, 0, 2, 3, 4);

splice第一个参数表示想要删除或插入元素的索引值,即数组的位置,第二个是删除的个数,0表示不删除,2,3,4表示将2,3,4依次插入到数组中。

numbers.splice(5, 3, 2, 3, 4);

上述代码表示,从5索引开始删除3个元素,并插入后面的2,3,4数字。

多维数组

JavaScript 只支持一维数组,并不支持矩阵。但是,我们可以用数组套数组,实现矩阵或任一多维数组。代码也可以写成如下这样。

let averageTemp = [];
// day 1
averageTemp[0] = [];
averageTemp[0][0] = 72;
averageTemp[0][1] = 75;
averageTemp[0][2] = 79;
averageTemp[0][3] = 79;
averageTemp[0][4] = 81;
averageTemp[0][5] = 81;
// day 2
averageTemp[1] = [];
averageTemp[1][0] = 81;
averageTemp[1][1] = 79;
averageTemp[1][2] = 75;
averageTemp[1][3] = 75;
averageTemp[1][4] = 73;
averageTemp[1][5] = 73;

使用console.table()可以以表格的形式打印出来:

数组方法

除了上述提到的方法,Js数组还提供了很多方法,常用如下:

1.数组合并

const zero = 0;
const positiveNumbers = [1, 2, 3];
const negativeNumbers = [-3, -2, -1];
let numbers = negativeNumbers.concat(zero, positiveNumbers);
//  [-3, -2, -1, 0, 1, 2, 3]

2.迭代器

  1. every
  2. some
  3. forEach
  4. map
  5. filter
  6. reduce
function isEven(x) { // 如果 x 是 2 的倍数,就返回 true console.log(x); return x % 2 === 0 ? true : false;
}
// ES2015(ES6)简写: const isEven = x => x % 2 === 0;
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];1. every : 当返回false的时候停止
numbers.every(isEven);
// 12. some : 当返回true的时候停止
numbers.some(isEven);
// 1
// 23. forEach : 相当于for,无返回值
numbers.forEach(x => console.log(x % 2 === 0));
// false true false true ...4. map :相当于for,返回一个包含所有返回值的数组
const myMap = numbers.map(isEven);
//
[false, true,  false,true,  false, true,false, true,  false,true,  false, true,false, true,  false
]5. filter :返回满足条件的值(即返回true的值),
const evenNumbers = numbers.filter(isEven);
//
[2,  4,  6, 8,10, 12, 14
]6. reduce :接收一个有如下四个参数的函数:previousValue、currentValue、index和array。index和array是可选的参数。
函数式编程:返回数组的累加
const reduceNumbers = numbers.reduce((previous, current) => previous + current);
//  120

3.ES6新方法

for of 循环迭代

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
for (const n of numbers) { console.log(n % 2 === 0 ? 'even' : 'odd');
}

@@iterator对象

通过Symbol.iterator访问并执行函数,返回iterator对象,iterator对象有个next函数,每次执行,返回结果:{value: 2, done: false},通过.value访问值,done的值为false意味着还有可迭代的值。

let iterator = numbers[Symbol.iterator]();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
console.log(iterator.next().value); // 4
console.log(iterator.next().value); // 5

也可以通过for of来循环输出

iterator = numbers[Symbol.iterator]();
for (const n of iterator) { console.log(n);
}

entries、keys和values方法

entries方法返回包含键值对的@@iterator;使用集合、字典、散列表等数据结构时,能够取出键值对是很有用。

let aEntries = numbers.entries(); // 得到键值对的迭代器
console.log(aEntries.next().value); // [0, 1] - 位置 0 的值为 1
console.log(aEntries.next().value); // [1, 2] - 位置 1 的值为 2
console.log(aEntries.next().value); // [2, 3] - 位置 2 的值为 3
// 也可用for of 迭代
aEntries = numbers.entries();
for (const n of aEntries) { console.log(n);
}

keys方法返回包含数组索引的@@iterator,value表示元素的索引,done属性的值为false,就意味着还有可迭代的值。

一旦没有可迭代的值,aKeys.next()就会返回一个value属性为undefined、done属性为true的对象。

const aKeys = numbers.keys(); // 得到数组索引的迭代器
console.log(aKeys.next()); // {value: 0, done: false }
console.log(aKeys.next()); // {value: 1, done: false }
console.log(aKeys.next()); // {value: 2, done: false }

values方法返回包含数组的值的@@iterator。

const aValues = numbers.values();
console.log(aValues.next()); // {value: 1, done: false }
console.log(aValues.next()); // {value: 2, done: false }
console.log(aValues.next()); // {value: 3, done: false }

Array.from 方法

Array.from可以根据已有数组创建一个新数组,也可根据函数过滤。

let numbers2 = Array.from(numbers);
[1,  2,  3,  4,  5,  6,7,  8,  9, 10, 11, 12,13, 14, 15
]
let evens = Array.from(numbers, x => (x % 2 == 0));
[false, true,  false,true,  false, true,false, true,  false,true,  false, true,false, true,  false
]

Array.of 方法

Array.of方法根据传入的参数创建一个新数组。以下面的代码为例。

let numbers3 = Array.of(1);
let numbers4 = Array.of(1, 2, 3, 4, 5, 6);
// 它和下面这段代码的效果一样。
let numbers3 = [1];
let numbers4 = [1, 2, 3, 4, 5, 6];
// 也可以用该方法复制已有的数组,如下所示,(...)可以展开数组。
let numbersCopy = Array.of(...numbers4);

fill 方法

fill方法用静态值填充数组。以下面的代码为例。

let numbersCopy = Array.of(1, 2, 3, 4, 5, 6);
// numbersCopy数组的length是 6,也就是有 6 个位置。再看下面的代码。
numbersCopy.fill(0);
// numbersCopy数组所有位置上的值都会变成 0([0, 0, 0, 0, 0, 0])。我们还可以指定开始填充的索引,如下所示。
numbersCopy.fill(2, 1);
// 上面的例子里,数组中从 1 开始的所有位置上的值都是 2([0, 2, 2, 2, 2, 2])。 同样,我们也可以指定结束填充的索引。
numbersCopy.fill(1, 3, 5);
// 在上面的例子里,我们会把 1 填充到数组索引 3 到 5 的位置(不包括 3 和 5),得到的数组为[0, 2, 2, 1, 1, 2]。
// 创建数组并初始化值的时候,fill方法非常好用,就像下面这样。
let ones = Array(6).fill(1);
// 上面的代码创建了一个长度为 6、所有值都是 1 的数组([1, 1, 1, 1, 1, 1])。

copyWithin 方法

copyWithin方法复制数组中的一系列元素到同一数组指定的起始位置。

array.copyWithin(target, start,end)

target为指定起始位置(必须),start为元素复制的起始索引位置,end为停止复制的索引位置 (默认为array .length)

let copyArray = [1, 2, 3, 4, 5, 6];
// 假如我们想把 4、5、6 三个值复制到数组前三个位置,得到[4, 5, 6, 4, 5, 6]这个数组,可以用下面的代码达到目的。
copyArray.copyWithin(0, 3);
// 假如我们想把 4、5 两个值(在位置 3 和 4 上)复制到位置 1 和 2,可以这样做:
copyArray = [1, 2, 3, 4, 5, 6];
copyArray.copyWithin(1, 3, 5);
// 这种情况下,会把从位置 3 开始到位置 5 结束(不包括 3 和 5)的元素复制到位置 1,结果是得到数组[1, 4, 5, 4, 5, 6]。

4.排序

反序输出数组numbers(它本来的排序是1, 2, 3, 4, …, 15)

numbers.reverse();

输出numbers的话就会看到[15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],此时使用sort方法

numbers.sort();

结果会是[1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9]。看起来不大对,是吧?这是因为sort方法在对数组做排序时,把元素默认成字符串进行相互比较。

我们可以传入自己写的比较函数。因为数组里都是数,所以可以像下面这样写。
numbers.sort((a, b) => a - b);

b大于a时,这段代码会返回负数,反之则返回正数。如果相等的话,就会返回 0。也就是说返回的是负数,就说明a比b小,这样sort就能根据返回值的情况对数组进行排序。

之前的代码也可以表示成如下这样,会更清晰一些。

function compare(a, b) {if (a < b) {return -1;}if (a > b) {return 1;}// a 必须等于 breturn 0;
}
numbers.sort(compare);

① 自定义排序

const friends = [ { name: 'John', age: 30 }, { name: 'Ana', age: 20 }, { name: 'Chris', age: 25 }, // ES2017 允许存在尾逗号
];
function comparePerson(a, b) { if (a.age < b.age) { return -1; } if (a.age > b.age) { return 1; } return 0;
}
console.log(friends.sort(comparePerson));
//
[{ name: 'Ana', age: 20 },{ name: 'Chris', age: 25 },{ name: 'John', age: 30 }
]

② 字符串排序

假如有这样一个数组。
let names = ['Ana', 'ana', 'john', 'John']; console.log(names.sort());
你猜会输出什么?答案如下所示。
["Ana", "John", "ana", "john"]
既然a在字母表里排第一位,为何ana却排在了John之后呢?这是因为 JavaScript 在做字
符比较的时候,是根据字符对应的 ASCII 值来比较的。例如,A、J、a、j对应的 ASCII 值分别是65、74、97、106。虽然a在字母表里是最靠前的,但J的 ASCII 值比a的小,所以排在了a前面。

更多关于 ASCII 表的信息,请访问 http://www.asciitable.com/。

如果使用sort来忽略大小写:

names = ['Ana', 'ana', 'john', 'John']; // 重置数组的初始状态
console.log(names.sort((a, b) => {if (a.toLowerCase() < b.toLowerCase()) {return -1;}if (a.toLowerCase() > b.toLowerCase()) {return 1;}return 0;
}));
// ['Ana', 'ana', 'john', 'John']

你会发现数组没有变化,因为都变成小写来比较,所以当两者相同时,保持了原有的顺序。

如果希望小写字母排在前面,那么需要使用localeCompare方法。
names.sort((a, b) => a.localeCompare(b));

最后输出[ ‘ana’, ‘Ana’, ‘john’, ‘John’ ]

假如对带有重音符号的字符做排序的话,也可以用localeCompare来实现。
const names2 = ['Maève', 'Maeve'];

console.log(names2.sort((a, b) => a.localeCompare(b)));

最后输出的结果将是[“Maeve”, “Maève”]。

5.搜索

indexOf方法返回与参数匹配的第一个元素的索引;

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
console.log(numbers.indexOf(10));
// 9
console.log(numbers.indexOf(100));
// -1 没找到

lastIndexOf返回与参数匹配的最后一个元素的索引。

numbers.push(10);
console.log(numbers.lastIndexOf(10));
// 15
console.log(numbers.lastIndexOf(100));
// -1

① ES6——find和findIndex方法

find和findIndex方法接收一个回调函数,搜索一个满足回调函数条件的值。下面的例子
里,我们要从数组里找一个 13 的倍数。find和findIndex的不同之处在于,find方法返回第一个满足条件的值,findIndex方法则返回这个值在数组里的索引。如果没有满足条件的值,find会返回undefined,而findIndex返回-1。

let numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
function multipleOf13(element, index, array) { return (element % 13 == 0);
}
console.log(numbers.find(multipleOf13));
// 13
console.log(numbers.findIndex(multipleOf13));
// 12

② ES7——includes方法

如果数组里存在某个元素,includes方法会返回true,否则返回false。使用includes
方法的例子如下。
console.log(numbers.includes(15)) // true

console.log(numbers.includes(20)) // false

可给includes方法传入一个起始索引,搜索会从索引指定的位置开始。

let numbers2 = [7,6,5,4,3,2,1];

console.log(numbers2.includes(4,5));// false,从第四位开始搜索,因此错过了5

6.输出字符串

① toString()方法

console.log(numbers.toString()); //1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

② join()方法

const numbersString = numbers.join('-');
console.log(numbersString); // '1-2-3-4-5-6-7-8-9-10-11-12-13-14-15'

7.官方文档

Array - JavaScript | MDN (mozilla.org)

类型数组

与C 和 Java 等其他语言不同,JavaScript 数组不是强类型的,因此它可以存储任意类型的
数据。类型数组则用于存储单一类型的数据。它的语法是let myArray = new TypedArray
(length),其中TypedArray需替换为下表所列之一。

let length = 5;
let int16 = new Int16Array(length);
for (let i=0; i<length; i++){
int16[i] = i+1;
}
console.log(int16);

使用 WebGL API、进行位操作、处理文件和图像时,类型数组都可以大展拳脚。它用起来和普通数组毫无二致,本章所学的数组方法和功能都可以用于类型数组。https://www.html5rocks.com/en/tutorials/webgl/typed_arrays/是一个很好的教程,讲解了如何使用类型数组处理二进制数据,以及它在实际项目中的应用。

TypeScript中的数组

TypeScript 会在编译时进行类型检测,来确保只对所有值都属于相同数据类型的数组进行操作。

根据类型推断,TypeScript 能够理解numbers数组的声明和const numbers: number[]是一样的。

interface Person { name: string; age: number;
} // const friends: {name: string, age: number}[]; 与下述方式一样
const friends = [ { name: 'John', age: 30 }, { name: 'Ana', age: 20 }, { name: 'Chris', age: 25 }
]; function comparePerson(a: Person, b: Person) { // comparePerson 函数的内容
}

总结

本文学习了JavaScript数组的基本用法,为下篇文章——栈做铺垫,也简单介绍了Typescript的数组,自己在学习的过程中也是学到了一些平时不怎么用的新东西,希望对你也有些帮助,这里是GIS宇宙,我们下期再见。

参考文献:

Array - JavaScript | MDN (mozilla.org)

学习JavaScript数据结构与算法第三版 Learning JavaScript Data Structures and Algorithms 3rd Edition ([巴西]格罗纳(LoianeGroner), 孙晓博, 邓钢, 吴双, 陈迪, 袁源) (z-lib.org)

本人其他平台账号:

  • 微信公众号:GIS宇宙
  • CSDN:GIS_宇宙
  • 知乎:GIS宇宙
  • 掘金:GIS宇宙

【算法与数据结构】JS基础——数组相关推荐

  1. js 数组 实现 完全树_算法和数据结构 | 树状数组(Binary Indexed Tree)

    本文来源于力扣圈子,作者:胡小旭.点击查看原文 力扣​leetcode-cn.com 树状数组或二叉索引树(英语:Binary Indexed Tree),又以其发明者命名为 Fenwick 树.其初 ...

  2. 【算法与数据结构】——后缀数组

    参考后缀数组 基数排序 后缀数组的实现用到了基数排序,简单介绍一下基数排序的内容. 基数排序是桶排序的一种扩展,是一种多关键字的排序方法.若记录按照多个关键字排序,则依次按照这些关键字进行排序. 例如 ...

  3. 算法与数据结构(稀疏数组)

    稀疏数组 Sparse Array 当一个数组中有大量元素相同时,可以用稀疏数组来表示,通过将有用信息记录在小规模的数组中来缩减程序规模 原数组: [0000102000300000004000000 ...

  4. 算法与数据结构 --- 串,数组和广义表 --- 串

    第一部分 --- 串的定义 1.主串和子串的关系和集合跟子集之间的关系类似但不相同,主串的子串必须是由主串中连续的字符组成的!!!,真子串是不包含主串本身的所有子串 1.字符位置是:串从左往右,从1开 ...

  5. js基础---数组方法

    数组数据的排序及去重 sort无形参的排序方式 arr1=[2,12,3,15];var a=arr1.sort();console.log(arr1);console.log(a);//排序会改变原 ...

  6. JS基础-数组的常用方法(ES3)

    数组的常用方法 数组是一个复杂数据类型,我们在操作它的时候就不能再像基本数据类型一样操作了 比如我们想改变一个数组 // 创建一个数组 var arr = [1, 2, 3]​ // 我们想把数组变成 ...

  7. 算法与数据结构 --- 串,数组与广义表 --- 数组

    第一部分 --- 数组的定义 1.二维数组可以理解为一维数组的堆叠 2.二维数组既可以看作一个线性结构,也可以看作是一个非线性结构,所以我们将二维数组看作是一个特殊的线性结构,它是线性结构的拓展 (线 ...

  8. 利用for循环调用插入方法批量插入 一条失败_算法与数据结构(1):基础部分——以插入排序为例...

    本文将会以插入排序为例,介绍算法与数据结构的基础部分. 插入排序 排序可以说是整个算法中最为基础,最为重要的一部分,而插入排序正是排序算法中最简单的一种解决办法. 什么是排序问题? 输入:n个数的一个 ...

  9. Caché 算法与数据结构

    第一章 Caché 算法与数据结构 基础和概念 ☆☆☆☆☆ 第二章 Caché 算法与数据结构 数组原理 ☆☆☆☆☆ 第三章 Caché 算法与数据结构 链表原理 ☆☆☆☆☆ 第四章 Caché 算法 ...

最新文章

  1. 基于android的记账本论文,(毕业论文)基于安卓的记账本.doc
  2. vue源码-对于「计算属性」的理解
  3. python真实环境与虚拟环境均配置jupyter的方法,虚拟开发环境增加到notebook选项中
  4. c++11-type_traits类型萃取
  5. [SCM]源码管理 - perforce的集中授权+分布式团队+负载均衡+可扩展性+高可用性+灾难恢复...
  6. 欢乐纪中A组周六赛【2019.5.25】
  7. android常用网址
  8. 服务器虚拟化的主备,云服务器可以主备切换
  9. 玻璃质感_几何体素描画法:几何体画法步骤教程和玻璃质感画法教程,快学习...
  10. 网站使用 VideoPlayer 方法
  11. 文件 - 介绍 含PEM文件
  12. 跳过休息日(周末和节假日)
  13. 请教:关于爬取歌词的一点疑惑
  14. 如何微调Segment Anything Model
  15. Linux作业 实现一个特殊的备份工具bak
  16. python画太极八卦图_「太极八卦图」使用HTML+CSS画太极八卦图 - seo实验室
  17. 并联四足机器人项目开源教程(三)--- 使用webots搭建仿真环境
  18. P2056 [ZJOI2007] 捉迷藏 【动态点分治】
  19. 在Windows Server 2008中创建密码重设盘 刘道军
  20. python查询实时天气预报_微信公众号+python+新浪SAE实现实时天气预报功能

热门文章

  1. linux 卸载32位rar,让CentOS能用yum自动安装rar和unrar
  2. 从医师考试泄题看内网安全
  3. 集群架构之LVS介绍
  4. 用QEMU搭建arm开发环境之三:编译BusyBox建立最简单的文件系统
  5. 使用上下游思维实现系统解耦
  6. pylon主要示例功能说明
  7. NTP网络时间服务器(北斗授时设备)应用平安城市天网工程
  8. Activiti常见操作数据表关系
  9. 内置MCU H323协议的会议录播一体机集成中控音频处理器
  10. 谷歌有超清实时卫星地图吗?