Skip to content

Map 和 Set-有序和无序

有序和无序,先看个例子

html
<p class="container" style="color: red" id="p1">
  <img src="xxx" alt="xxx.png" />
  <span>123</span>
</p>
<script>
  // vdom 虚拟 dom - 模拟真是的 dom 结构
  const p = {
    tag: 'p',
    props: {
      // 无序
      id: 'p1',
      className: 'container',
      style: 'color:red',
    },
    children: [
      // 有序
      {
        tag: 'img',
        props: {
          alt: 'xxx',
          src: 'xxx.png',
        },
      },
      {
        tag: 'span',
        children: [123],
      },
    ],
  };
  // js 中 Object 是无序的,Array 是有效的
</script>
  • 有序:操作慢
  • 无序:操作快,但无序
  • 如何结合两者优点呢? - 二叉树、及其变种

Map 和 Object 的区别

  • API 不同,Map 可以以任意类型为 key
  • Map 是有序结构(重要)
  • Map 操作同样很快
js
const obj1 = {
  2: 'hello',
  1: { x: 100 },
  3: 100,
};

// Object 是无序的
console.log(Object.keys(obj1)); // ['1', '2', '3']

// Object 有多快?
for (let i = 0; i < 1000 * 10000; i++) {
  obj1[i + ''] = i;
}
console.time('obj find');
obj1['2000000'];
console.timeEnd('obj find'); // obj find: 0.0068359375 ms

// Map Api: set,delete,has,forEach,size
const m = new Map([
  ['key1', 'hello'],
  ['key3', { x: 100 }],
  ['key2', 100],
]);

// Map 的 key 可以为任意类型
const obj2 = { name: 'xxx' };
m.set(obj2, 'object key');

function fn() {}

m.set(fn, 'fn key');

// 比如 obj1 和 obj2 关联,但是没有引用关系,保持独立
// m.set(obj1, obj2)

// Map 是有序的
m.forEach((value, key) => console.log(key, value)); // 保持顺序输出

// Map 有多快?
for (let i = 0; i < 1000 * 10000; i++) {
  m.set(i + '', i);
}
console.time('map find');
m.has('2000000');
console.timeEnd('map find'); // map find: 0.01416015625 ms

Set 和 Array 的区别

  • API 不同
  • Set 元素不能重复
  • Set 是无序结构,操作很快
js
const arr = [1, 2, 3, 4];
const set = new Set([1, 2, 2, 3, 4]);

// Map Api: add,delete,has,forEach,
set.forEach((val) => console.log(val));

// Set 元素是不能重复的(数组去重)
console.log(set); // Set(4){1, 2, 3, 4}

// Set 是无序的(快),arr 是有序的(慢)
for (let i = 0; i < 100 * 10000; i++) {
  arr.push(i);
}
console.time('arr unshift');
arr.unshift('a'); // 导致所有元素后移,所以慢
console.timeEnd('arr unshift'); // arr unshift: 0.25390625 ms
console.time('arr push');
arr.push('b');
console.timeEnd('arr push'); // arr push: 0.005859375 ms
console.time('arr find');
arr.includes('20000');
console.timeEnd('arr find'); // arr find: 0.89794921875 ms

for (let i = 0; i < 100 * 10000; i++) {
  set.add(i);
}
console.time('set add');
set.add('a');
console.timeEnd('set add'); // set add: 0.00390625 ms
console.time('set find');
set.has('20000');
console.timeEnd('set find'); // set find: 0.005859375 ms

基于 MIT 许可发布