一篇文章带你速通js哈希表(set,map)常用方法(求两个和哈希表的交集)

JavaScript 中的哈希表通常通过 `Object` 或者更常用的 `Map` 对象来实现。以下是这两种哈希表结构的一些常用方法:

### Object 方法

虽然 `Object` 可以用作哈希表,但它的键只能是字符串或符号(Symbol)。这里是一些常用的方法:

- `obj[key]`: 用于访问、添加或更新对象属性。
- `delete obj[key]`: 删除对象的某个属性。
- `Object.keys(obj)`: 返回一个由对象自身可枚举属性组成的数组。
- `Object.values(obj)`: 返回一个由对象自身可枚举属性对应的值组成的数组。
- `Object.entries(obj)`: 返回一个由对象自身可枚举属性及其对应值组成的数组。
- `hasOwnProperty(key)`: 检查对象是否具有特定的自有属性(不是继承的)。

### Map 方法

`Map` 是 ES6 引入的一种新的数据结构,它允许任何类型的键,并且保持插入顺序。以下是一些 `Map` 的常用方法:

- `new Map()`: 创建一个新的 Map 实例。
- `map.set(key, value)`: 添加或更新一个键值对。
- `map.get(key)`: 获取与指定键关联的值。
- `map.has(key)`: 检查 Map 中是否存在指定的键。
- `map.delete(key)`: 移除指定键及其关联的值。
- `map.clear()`: 移除 Map 中的所有键值对。
- `map.size`: 返回 Map 中键值对的数量。
- `map.forEach(callback[, thisArg])`: 对每个键值对执行一次提供的函数。
- `map.keys()`: 返回一个新的 Iterator 对象,该对象包含了按照插入顺序所有的键。
- `map.values()`: 返回一个新的 Iterator 对象,该对象包含了按照插入顺序所有的值。
- `map.entries()`: 返回一个新的 Iterator 对象,该对象包含了按照插入顺序所有的 [key, value] 数组。

使用 `Map` 相较于普通对象作为哈希表有几个优势,比如更好的性能(尤其是在大量数据时),以及内置的支持迭代和大小检查等特性。

求两个哈希表(或称为映射、字典)的交集,通常是指找到两个哈希表中键相同且对应的值也相同的项。根据具体需求,你可能只关心键的交集,或者同时关心键和值都匹配的项。下面是两种情况的实现方法:

### 1. 只关心键的交集

如果你只关心两个哈希表中键的交集,而不在乎它们对应的值是否相同,可以这样做:

```javascript
function getKeysIntersection(map1, map2) {
    // 将两个Map对象的键转换为Set集合
    const keys1 = new Set(map1.keys());
    const keys2 = new Set(map2.keys());

    // 找到交集
    const intersection = new Set([...keys1].filter(key => keys2.has(key)));

    return intersection;
}

// 示例使用
const map1 = new Map([['a', 1], ['b', 2], ['c', 3]]);
const map2 = new Map([['b', 4], ['c', 5], ['d', 6]]);

console.log(getKeysIntersection(map1, map2)); // 输出: Set { 'b', 'c' }
```

### 2. 关心键和值都匹配的项

如果你不仅关心键的交集,还要求这些键在两个哈希表中的值也相等,那么你可以这样实现:

```javascript
function getKeyValueIntersection(map1, map2) {
    const intersection = new Map();

    for (let [key, value] of map1) {
        if (map2.has(key) && map2.get(key) === value) {
            intersection.set(key, value);
        }
    }

    return intersection;
}

// 示例使用
const map1 = new Map([['a', 1], ['b', 2], ['c', 3]]);
const map2 = new Map([['b', 2], ['c', 3], ['d', 6]]);

console.log(getKeyValueIntersection(map1, map2)); // 输出: Map(2) { 'b' => 2, 'c' => 3 }
```

这两种方法分别适用于不同的场景。第一种方法只返回键的交集,而第二种方法则返回键和值都匹配的项。选择哪种方法取决于你的具体需求。

`Set` 和 `Map` 是 JavaScript 中两种不同的数据结构,它们各自有不同的用途和特性。以下是它们之间的主要区别:

### Set

1. **存储唯一值**:
   - `Set` 用于存储唯一的值(无论是原始值还是对象引用),不允许重复项。
   
2. **无键值对**:
   - `Set` 只存储单一的值,而不像 `Map` 那样以键值对的形式存储数据。

3. **迭代顺序**:
   - `Set` 的迭代顺序是插入顺序,即元素按照它们被添加到集合中的顺序进行迭代。

4. **常用方法**:
   - `add(value)`:向 `Set` 添加一个新元素。
   - `delete(value)`:从 `Set` 中移除指定的元素。
   - `has(value)`:检查 `Set` 是否包含某个元素。
   - `clear()`:移除 `Set` 中的所有元素。
   - `size`:返回 `Set` 中元素的数量。

5. **使用场景**:
   - 当你需要确保一组数据中没有重复项时,或者当你需要执行数学集合操作(如并集、交集、差集)时,`Set` 是非常有用的。

### Map

1. **键值对映射**:
   - `Map` 用于存储键值对,每个键都是唯一的,但可以关联任何类型的值。键可以是任意类型,包括对象、函数或原始值。

2. **保持插入顺序**:
   - `Map` 也保持键值对的插入顺序,这意味着当遍历 `Map` 时,你会按照它们被添加的顺序访问键值对。

3. **常用方法**:
   - `set(key, value)`:设置键/值对。
   - `get(key)`:获取与指定键关联的值。
   - `has(key)`:检查 `Map` 是否包含指定的键。
   - `delete(key)`:从 `Map` 中移除指定的键及其对应的值。
   - `clear()`:移除 `Map` 中的所有键值对。
   - `size`:返回 `Map` 中键值对的数量。

4. **使用场景**:
   - 当你需要将某些数据与特定的键关联起来,并且这些键可能是复杂的数据类型(如对象或函数)时,`Map` 提供了比对象更强大的功能。此外,`Map` 支持迭代器协议,因此可以直接在 `for...of` 循环中使用。

### 总结

- 使用 `Set` 来处理唯一值的集合,以及执行集合运算。
- 使用 `Map` 来创建键值对映射,尤其是当你需要使用非字符串类型的键时。

选择使用 `Set` 还是 `Map` 应该基于你具体的应用需求。如果你只需要存储一系列不重复的值,那么 `Set` 是更好的选择;如果你需要关联键和值,那么 `Map` 更适合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值