文章出自个人博客https://knightyun.github.io/2019/08/02/js-sparse-array,转载请申明


稀疏数组

概念

在一些后端语言中,如 C,数组内的值通常被分配在一系列连续的内存地址上,但是在 js 中,某些数组内存则不是连续的,所谓稀疏,顾名思义,不连续,存在一些空隙;

例如:

var arr = new Array(3);
console.log(arr);
// (3) [empty × 3]

通过以上方法创建数组,其中 Array(3) 中的参数 3 表示数组的长度,这个数组就是稀疏的,控制台输出一般带有 empty 字样,或者像下面这样创建数组:

var arr = [1,,2];
console.log(arr);
// (3) [1, empty, 2]

因为定义语句中两个逗号之间无字符,没有定义值,同样带有 empty 字样,代表稀疏数组,这里可以把 empty 理解为上面讲到的 空隙

特点

接下来看一下稀疏数组特殊在什么地方,举个例子说明:

var arr1 = [1, 2, 3];  // 正常数组
var arr2 = new Array(3);  // 稀疏数组
var arr3 = [1, , 3];  // 稀疏数组console.log(arr1.length, arr2.length, arr3.length);
// 3 3 3
console.log(arr2[0], arr3[1]);
// undefined undefined
for (var i = 0; i < 3; i++) {console.log(arr1[i], arr2[i], arr3[i]);
}
// 1 undefined 1
// 2 undefined undefined
// 3 undefined 3
arr1.forEach(function(x){console.log(x);
});
// 1
// 2
// 3
arr2.forEach(function(x){console.log(x);
});
// (无输出)
arr3.forEach(function(x){console.log(x);
});
// 1
// 3
console.log(0 in arr3, 1 in arr3);
// true false

总结一下,创建的稀疏数组,其长度(length)与定义长度值一致;空隙 值可以被单独访问到,并且不是之前出现的 empty 字样,而是 undefined,比如例子中出现 undefined 时都是使用 arr[i] 这样的索引直接访问方式;使用某些数组方法如 forEach() 时,会忽略掉空隙值,只处理正常值,所以也会使得 1 in arr3 值为 false,即数组中不存在该索引;

细想一下,js 这样处理的原因多半是去除不必要的性能开销,当数组相当大时,可以避免处理一些未初始化的值,但这样也同时使得开发中会出现一些问题,所以应尽量避免;

举个例子来查看一下性能如何:

console.time('one');
// 密集数组
Array(...Array(1e5)).forEach(function(){;
});
console.timeEnd('one');console.time('two');
// 稀疏数组
Array(1e5).forEach(function(){;
});
console.timeEnd('two');// one: 26.3759765625ms
// two: 5.701171875ms

可以看出在处理较大数组时,稀疏数组确实能降低不少性能开销;

密集数组

概念

与稀疏相对应,则存在密集,定义也就是元素中不存在 空隙 值,其实密集数组基本就是平时常见的正常数组;

例如:

var arr1 = [1, 2, 3];
var arr2 = new Array(1, 2, 3);
arr2.forEach(function(x){console.log(x);
});
// 1
// 2
// 3

以上都是一些定义密集数组的方法,并且数组中的值都能被正常访问或遍历处理;

区别

运用时需要注意以下情况:

var arr1 = [undefined, undefined, undefined];
var arr2 = new Array(3);
console.log(arr1[0], arr2[0]);
// undefined undefined
arr1.forEach(function(x){console.log(x);
})
// undefined
// undefined
// undefined
arr2.forEach(function(x){console.log(x);
})
// (无输出)

即显式的声明值为 undefined 并不代表这个值就是之前提到的空隙值,虽然二者通过索引访问时的值都返回 undefined,但是其根本还是有区别的,显式声明过的是可以被遍历等操作访问的,不会被当成空隙值被忽略;

拓展

通常在很多情况下,我们想要直接声明一个数组并赋予其一些特定的初始值,并且为了避免问题,通常是希望申明为密集数组的,下面就介绍一些常用的方法或技巧:

var arr1 = new Array(3).fill(1);
console.log(arr1);
// [1, 1, 1]var arr2 = Array.fill().map((x, i) => i);
console.log(arr2);
// [0, 1, 2]var arr3 = Array.apply(null, Array(3));
console.log(arr3);
// [undefined, undefined, undefined]
// 这样声明的是密集数组,不是稀疏的var arr4 = new Array(4).join('a').split('');
console.log(arr4);
// ['a', 'a', 'a']
// 注意定义数组长度比输出数组大 1

其它更多的方法可以自行类推;


技术文章推送 手机、电脑实用软件分享

JavaScript稀疏数组相关推荐

  1. 稀疏数组真心话大冒险

    An adventure in sparse arrays JavaScript 稀疏数组与孔(hole) - 简书 概念 稀疏数组(sparse array) 稀疏数组与密集数组最大的不同,就是稀疏 ...

  2. JavaScript中的稀疏数组与密集数组

    一般而言,javaScript中的数组是稀疏的,也就是说数组中的元素之间可以有空隙,因为一个数组其实就是一个键值映射.这篇本文解释了如何创建稀疏数组和不稀疏的数组,以及稀疏数组和密集数组之间的区别. ...

  3. javascript中数组的22种方法

    前面的话数组总共有22种方法,本文将其分为对象继承方法.数组转换方法.栈和队列方法.数组排序方法.数组拼接方法.创建子数组方法.数组删改方法.数组位置方法.数组归并方法和数组迭代方法共10类来进行详细 ...

  4. JavaScript之数组相关方法以及应用

    1,稀疏数组 稀疏数组是指数组中的某个下标未给出值或某个下标的值被删除.例如: let arrayOne=['xiaozi',,12,,true,23] let arrayTwo=[1,2,3,3,4 ...

  5. java 稀疏数组和二维数组转换,并保存稀疏数组到文件后可以读取

    稀疏数组和二维数组转换 稀疏数组:当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组 稀疏数组的处理方法: 记录数组一共有多少行,有多少个不同的值 把具有不同值得元素的行 ...

  6. 数据结构与算法---稀疏数组

    数据结构与算法-稀疏数组 1.基本介绍: ​ 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组. 2.稀疏数组的处理方法是: ​ (1)记录数组一共有几行几列,有多少个 ...

  7. 一、稀疏数组的实际应用和代码实现

    稀疏数组 1.实际需求 使用二维数组记录棋盘 2.分析问题 因为二维数组中的很多值都是默认值0,因此记录了很多没有意义的数据,由此我们引出稀疏数组 3.稀疏数组的基本介绍 (1)当一个数组中大部分元素 ...

  8. 深入理解JavaScript类数组

    起因 写这篇博客的起因,是我在知乎上回答一个问题时,说自己在学前端时把<JavaScript高级程序设计>看了好几遍. 于是在评论区中,出现了如下的对话: 天啦噜,这话说的,宝宝感觉到的, ...

  9. 通过ID在JavaScript对象数组中查找对象

    本文翻译自:Find object by id in an array of JavaScript objects I've got an array: 我有一个数组: myArray = [{'id ...

最新文章

  1. richTextBox设置选中的字体属性
  2. 深度学习项目-神经元结构可视化
  3. MFC中的几种播放声音的方法
  4. bzoj 3404: [Usaco2009 Open]Cow Digit Game又见数字游戏(SG函数)
  5. PAIP.利用SyncML协议来同步备份手机短信联系人.txt
  6. 22_多易教育之《yiee数据运营系统》用户画像-消费行为性别预测篇
  7. Arduino 超声波避障循迹小车,四轮智能小车
  8. openwrt网关服务器性能,单一ipv6地址做网关的三种方法之openwrt篇
  9. 深信服2019届校园招聘专场(私聊博主得内推码,免简历筛选)
  10. 机器学习是什么?详解机器学习概念
  11. Net2 A Graph Attention Network Method
  12. 压力测试工具tsung
  13. 父母教养方式与幼儿焦虑关系的三水平元分析
  14. 谁发明了计算机人工智能,麻省理工学院发明了人工智能芯片
  15. 转载文章,让大家一起探讨,
  16. 视网膜图像分割数据集整理
  17. 产品经理的金字塔之旅---将“打杂”的实习经历描述的高大上!!!
  18. [ESP32]学习笔记05
  19. 饺子(节操)播放器集成问题
  20. python 图标字体_Python+PyQt:使用图标字体打造无边框通用导航界面

热门文章

  1. Delphi XE的RTTI增强,动态Hook某些内部事件
  2. python之字符编码(四)
  3. [APUE]进程控制(中)
  4. 转载 Div+css浏览器兼容实例分析(一)
  5. jvm学习笔记(1)——java虚拟机内存区域
  6. 【Nginx】实现负载均衡的几种方式
  7. 华硕z170a如何开启m2_「科技犬」新品游戏本、翻转屏评测汇总:华硕微星荣耀戴尔,选谁...
  8. 【nacos系列】windows安装与配置nacos
  9. SpringBoot使用ELK日志收集
  10. 查看gradle dependencies