open-index/open-npm huggingface dataset:
npm package: @henhal/mapset
Description: A MapSet implementation, behaving like a Set for insertion and iteration of arbitrary indexable objects, and as a map for retrieval using index keys.
Author: Henrik Hall
Latest version: 1.0.2

# MapSet

## Introduction

A `MapSet` is a class partially implementing the standard JavaScript `Set` and `Map` classes,
allowing insertion of arbitrary objects which can be indexed using a `key: (item: V) => K` function supplied to the constructor, as opposed to the standard `Set` which only supports object reference equality for objects.

## Installation

```
$ npm install mapset
```

## Description
The class behaves like a `Set` for insertion: `add(value: V)` and iteration of values, 
and as a `Map` for key-based operations like `get(key: K)`, `has(key: K)` and `delete(key: K)`.

This enables adding unique objects in the same way as for a standard `Set`, but where the uniqueness is defined by the `key` function, 
while at the same time allowing `Map` operations to operate on the collection using keys.   

To simplify typing, two interfaces defining the parts of `Set` and `Map` supported by `MapSet` are also defined, so that

* `Set<V>` implements `PartialSet<V>`
* `Map<K, V>` implements `PartialMap<K, V>`
* `MapSet<K, V>` implements `PartialSet<V>` and `PartialMap<K, V>`

This means that at an interface may refer to a `PartialSet` or a `PartialMap` and be implemented either by
the standard `Set` and `Map` classes, or by `MapSet`.

### Differences from `Set` and `Map`:

Properties missing from `Set`:

* `keys()` - replaced by same method in `Map` returning `IterableIterator<K>` instead of `IterableIterator<V>`
* `entries()` - replaced by same method in `Map` returning `IterableIterator<[K, V]>` instead of `IterableIterator<[V, V]>`
* `delete(value: V)` - replaced by same method in `Map` taking a key instead of a value
* `has(value: V)` - replaced by same method in `Map` taking a key instead of a value
* `forEach(callbackfn: (value: V, value2: V, map: Set<V>) => void, thisArg?: any)` - replaced by same method in `Map` calling the callback with `(value: V, key: K, map: this)`

Properties missing from `Map`:

* `[Symbol.iterator]()` - replaced by same method in `Set` returning `IterableIterator<V>` instead of `IterableIterator<[K, V]>`
* `set(key: K, value: V)` - replaced by `add` method in `Set` automatically calculating the key from the value using the `key` function, to prevent inconsistent items in the `MapSet`

## Example usage

```
interface Foo {
  id: string;
  name?: string;
  age?: number;
}

const foos = new MapSet((item: Foo) => item.id); // MapSet<string, Foo>

foos.add({id: '42', name: 'John Doe'});
foos.add({id: '42', name: 'Jane Doe'}); // replaces John
foos.add({id: '79', name: 'Foo Bar'});

for (const foo of foos) {
  console.log(foo);
} 

foos.size; // 2
foos.has('79'); // true
foos.get('42'); // {id: '42', name: 'Jane Doe'}
foos.get('7'); // undefined
foos.delete('79'); // true
foos.has('79'); // false

```