flat-pair 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,8 +14,9 @@ For more awesome packages, check out [my homepage💛](https://baendlorel.github
14
14
  - 🛡️ **Type Safe**: Full TypeScript support with generic types
15
15
  - 🎯 **Zero Cost**: Static methods available for minimal overhead
16
16
  - ⚡ **Lightweight**: No dependencies, minimal bundle size
17
+ - 🌲 **Native Behavior**: `forEach`, `find` acts like they are in `Array`. Equality check uses `SameValueZero`
17
18
 
18
- ## Installation
19
+ ## Installation / Import
19
20
 
20
21
  ```bash
21
22
  npm install flat-pair
@@ -23,98 +24,33 @@ npm install flat-pair
23
24
  pnpm install flat-pair
24
25
  ```
25
26
 
26
- ## Quick Start
27
-
28
- ### Using the FlatPair Class
29
-
30
27
  ```typescript
31
- import { FlatPair } from 'flat-pair';
32
-
33
- // Create from Map
34
- const map = new Map([
35
- ['name', 'John'],
36
- ['age', 25],
37
- ]);
38
- const flatPair = FlatPair.from(map);
39
-
40
- // Or create directly
41
- const pair = new FlatPair(['name', 'John', 'age', 25]);
42
-
43
- // Add key-value pairs (won't add duplicates)
44
- pair.add('city', 'New York');
45
- pair.add('name', 'Jane'); // Won't override existing key
46
-
47
- // Find by key
48
- console.log(pair.find('name')); // 'John'
49
-
50
- // Find by value
51
- console.log(pair.findByValue('New York')); // 'city'
52
-
53
- // Remove pairs
54
- pair.remove('age'); // returns true
55
- pair.remove('nonexistent'); // returns false
56
-
57
- // Get size
58
- console.log(pair.size); // 2
59
-
60
- // Clear all
61
- pair.clear();
28
+ import { FlatPair, FlatPairOperator, add, get, find ...others } from 'flat-pair';
62
29
  ```
63
30
 
64
- ### Iteration and at()
65
-
66
- FlatPair implements iterator helpers similar to `Map` and arrays:
67
-
68
- - `forEach()` - like normal `forEach` from Array
69
- - `keys()` - returns an iterator over keys
70
- - `values()` - returns an iterator over values
71
- - `entries()` - returns an iterator over [key, value] pairs
72
- - `Symbol.iterator` - the default iterator, same as `entries()`
73
- - `at(index)` - returns the [key, value] pair at zero-based index or `undefined` if out of range
74
-
75
- ```typescript
76
- // keys / values / entries
77
- console.log([...fp.keys()]); // ['a','b']
78
- console.log([...fp.values()]); // [1,2]
79
- console.log([...fp.entries()]); // [['a',1], ['b',2]]
80
-
81
- // default iterator
82
- for (const [k, v] of fp) {
83
- console.log(k, v);
84
- }
85
-
86
- // at
87
- console.log(fp.at(0)); // ['a', 1]
88
- console.log(fp.at(2)); // undefined
89
- ```
31
+ ## Quick Start
90
32
 
91
- ### forEach
33
+ ### FlatPair Class
92
34
 
93
- `forEach` iterates pairs and follows the callback signature `(value, key, index, arr)` and accepts an optional `thisArg`.
35
+ `FlatPair` is a container class has an `items` array, it has methods that wrap the static functions for easier usage.
94
36
 
95
37
  ```typescript
96
- fp.forEach(
97
- function (value, key, index, arr) {
98
- console.log(index, key, value, arr === (fp as any).items);
99
- },
100
- { myThis: true }
101
- );
38
+ // userId - detail pair
39
+ const pairs = new FlatPair<number, Detail>();
40
+ pairs.add(1, { name: 'Alice', age: 30 });
41
+ pairs.add(2, { name: 'Bob', age: 25 });
42
+ pairs.remove(1);
43
+ pairs.find((value, key) => value.age > 20);
102
44
  ```
103
45
 
104
46
  ### Using Static Functions (Zero Cost)
105
47
 
106
48
  ```typescript
107
- import { add, find, findByValue, remove, size, clear } from 'flat-pair';
108
-
109
49
  const items: any[] = [];
110
50
 
111
51
  // Add items
112
- add(items, 'name', 'John');
113
- add(items, 'age', 25);
114
-
115
- // Find operations
116
- const name = find(items, 'name'); // 'John'
117
- const ageKey = findByValue(items, 25); // 'age'
52
+ add<string, string>(items, 'name', 'John');
53
+ add<string, number>(items, 'age', 12);
118
54
 
119
55
  // Remove and other operations
120
56
  remove(items, 'age'); // returns true
@@ -124,17 +60,19 @@ clear(items); // empties the array
124
60
 
125
61
  ### Using FlatPairOperator Class (For fixed type hint)
126
62
 
63
+ If you don't want to specify the generic types every time you call a static function, you can use `FlatPairOperator` which wraps the static functions with fixed generic types.
64
+
127
65
  ```typescript
128
66
  import { FlatPairOperator } from 'flat-pair';
129
67
 
130
68
  const operator = new FlatPairOperator<string, number>();
131
69
  const items: any[] = [];
132
70
 
133
- operator.add(items, 'score', 100);
71
+ operator.add(items, 'score', 100); // operator's add method is always typed
134
72
  operator.add(items, 'level', 5);
135
73
 
136
- console.log(operator.find(items, 'score')); // 100
137
- console.log(operator.findByValue(items, 5)); // 'level'
74
+ console.log(operator.get(items, 'score')); // 100
75
+ console.log(operator.getByValue(items, 5)); // 'level'
138
76
  ```
139
77
 
140
78
  ## Performance
package/dist/index.d.ts CHANGED
@@ -1,19 +1,27 @@
1
1
  declare class FlatPair<K, V> {
2
2
  static from<T extends Map<any, any>>(map: T): T extends Map<infer K, infer V> ? FlatPair<K, V> : never;
3
- private readonly items;
3
+ private readonly _items;
4
4
  constructor(items: any[]);
5
5
  get size(): number;
6
+ /**
7
+ * A reference to the internal array
8
+ * - associated with `this.findIndex`
9
+ */
10
+ get array(): any[];
6
11
  /**
7
12
  * Will check if the key already exists, if so then do nothing.
8
13
  */
9
14
  add(key: K, value: V): this;
15
+ hasByValue(value: V): boolean;
10
16
  remove(key: K): boolean;
11
17
  removeByValue(value: V): boolean;
12
- find(key: K): V | undefined;
13
- findByValue(value: V): K | undefined;
14
- at(pairIndex: number): [K, V] | undefined;
18
+ get(key: K): V | undefined;
19
+ getByValue(value: V): K | undefined;
20
+ find(predicate: (value: V, key: K, index: number, array: any[]) => boolean): [K, V] | undefined;
21
+ findIndex(predicate: (value: V, key: K, index: number, array: any[]) => boolean): number;
15
22
  clear(): void;
16
- forEach(callback: (value: V, key: K, pairIndex: number, array: any[]) => void, thisArg?: any): void;
23
+ has(key: K): boolean;
24
+ forEach(callback: (value: V, key: K, index: number, array: any[]) => void, thisArg?: any): void;
17
25
  keys(): IterableIterator<K>;
18
26
  values(): IterableIterator<V>;
19
27
  entries(): IterableIterator<[K, V]>;
@@ -26,30 +34,36 @@ declare class FlatPair<K, V> {
26
34
  declare class FlatPairOperator<K, V> {
27
35
  add(items: any[], key: K, value: V): void;
28
36
  remove(items: any[], key: K): boolean;
29
- find(items: any[], key: K): V | undefined;
30
- findByValue(items: any[], value: V): K | undefined;
37
+ get(items: any[], key: K): V | undefined;
38
+ getByValue(items: any[], value: V): K | undefined;
39
+ find(items: any[], predicate: (value: V, key: K, index: number, array: any[]) => boolean): [K, V] | undefined;
40
+ findIndex(items: any[], predicate: (value: V, key: K, index: number, array: any[]) => boolean): number;
31
41
  removeByValue(items: any[], value: V): boolean;
32
- forEach(items: any[], callback: (value: V, key: K, pairIndex: number, array: any[]) => void, thisArg?: any): void;
33
- at(items: any[], pairIndex: number): [K, V] | undefined;
42
+ forEach(items: any[], callback: (value: V, key: K, index: number, array: any[]) => void, thisArg?: any): void;
34
43
  keys(items: any[]): IterableIterator<K>;
35
44
  values(items: any[]): IterableIterator<V>;
36
45
  entries(items: any[]): IterableIterator<[K, V]>;
37
46
  clear(items: any[]): void;
47
+ has(items: any[], key: K): boolean;
48
+ hasByValue(items: any[], value: V): boolean;
38
49
  }
39
50
 
40
- declare function add<K, V>(items: any[], key: K, value: V): void;
41
51
  declare function size(items: any[]): number;
42
- declare function find<K, V>(items: any[], key: K): V | undefined;
43
- declare function findByValue<K, V>(items: any[], value: V): K | undefined;
52
+ declare function add<K, V>(items: any[], key: K, value: V): void;
53
+ declare function has<K>(items: any[], key: K): boolean;
54
+ declare function hasByValue<V>(items: any[], value: V): boolean;
55
+ declare function get<K, V>(items: any[], key: K): V | undefined;
56
+ declare function getByValue<K, V>(items: any[], value: V): K | undefined;
44
57
  declare function remove<K>(items: any[], key: K): boolean;
45
58
  declare function removeByValue<V>(items: any[], value: V): boolean;
46
59
  /**
47
60
  * Behaviors are similar to `Array.prototype.forEach`, caches length and checks index existence.
48
61
  *
49
- * - `callback`: real index in the `arr` is `2 * pairIndex`.
62
+ * - `callback`: index is the index of array, not the pair count.
50
63
  */
51
- declare function forEach<K, V>(items: any[], callback: (value: V, key: K, pairIndex: number, array: any[]) => void, thisArg?: any): void;
52
- declare function at<K, V>(items: any[], pairIndex: number): [K, V] | undefined;
64
+ declare function forEach<K, V>(items: any[], callback: (value: V, key: K, index: number, array: any[]) => void, thisArg?: any): void;
53
65
  declare function clear(items: any[]): void;
66
+ declare function find<K, V>(items: any[], predicate: (value: V, key: K, index: number, array: any[]) => boolean): [K, V] | undefined;
67
+ declare function findIndex<K, V>(items: any[], predicate: (value: V, key: K, index: number, array: any[]) => boolean): number;
54
68
 
55
- export { FlatPair, FlatPairOperator, add, at, clear, find, findByValue, forEach, remove, removeByValue, size };
69
+ export { FlatPair, FlatPairOperator, add, clear, find, findIndex, forEach, get, getByValue, has, hasByValue, remove, removeByValue, size };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- function t(t,e,r){const n=t.length;for(let r=0;r<n;r+=2)if(t[r]===e)return;t.push(e,r)}function e(t){const e=t.length;if(e%2!=0)throw new Error("Invalid items length, must be even number");return e/2}function r(t,e){const r=t.length;for(let n=0;n<r;n+=2)if(t[n]===e)return t[n+1]}function n(t,e){const r=t.length;for(let n=1;n<r;n+=2)if(t[n]===e)return t[n-1]}function i(t,e){const r=t.length;for(let n=0;n<r;n+=2)if(t[n]===e)return t.splice(n,2),!0;return!1}function o(t,e){const r=t.length;for(let n=1;n<r;n+=2)if(t[n]===e)return t.splice(n-1,2),!0;return!1}function s(t,e,r){let n=0;const i=t.length;for(let o=0;o<i;o+=2)o in t&&e.call(r,t[o+1],t[o],n,t),n++}function u(t,e){if(e<0)return;const r=2*e;return r+1>=t.length?void 0:[t[r],t[r+1]]}function f(t){t.length=0}class l{static from(t){if("[object Map]"!==Object.prototype.toString.call(t))throw new TypeError("[FlatPair: __func__] Argument must be a Map");const e=[];return t.forEach((t,r)=>e.push(r,t)),new l(e)}items=[];constructor(t){if(t.length%2!=0)throw new TypeError("FlatPair items length must be even");this.items=t}get size(){return this.items.length/2}add(e,r){return t(this.items,e,r),this}remove(t){return i(this.items,t)}removeByValue(t){return o(this.items,t)}find(t){return r(this.items,t)}findByValue(t){return n(this.items,t)}at(t){return u(this.items,t)}clear(){this.items.length=0}forEach(t,e){s(this.items,t,e)}*keys(){for(let t=0;t<this.items.length;t+=2)yield this.items[t]}*values(){for(let t=1;t<this.items.length;t+=2)yield this.items[t]}*entries(){for(let t=0;t<this.items.length;t+=2)yield[this.items[t],this.items[t+1]]}[Symbol.iterator](){return this.entries()}}class c{add(e,r,n){t(e,r,n)}remove(t,e){return i(t,e)}find(t,e){return r(t,e)}findByValue(t,e){return n(t,e)}removeByValue(t,e){return o(t,e)}forEach(t,e,r){s(t,e,r)}at(t,e){return u(t,e)}*keys(t){for(let e=0;e<t.length;e+=2)yield t[e]}*values(t){for(let e=1;e<t.length;e+=2)yield t[e]}*entries(t){for(let e=0;e<t.length;e+=2)yield[t[e],t[e+1]]}clear(t){t.length=0}}export{l as FlatPair,c as FlatPairOperator,t as add,u as at,f as clear,r as find,n as findByValue,s as forEach,i as remove,o as removeByValue,e as size};
1
+ const e=function(e,r){return e===r||e!=e&&r!=r};function r(e){const r=e.length;if(r%2!=0)throw new TypeError("[FlatPair: size] items length must be even number");return r/2}function t(r,t,n){const i=r.length;if(i%2!=0)throw new TypeError("[FlatPair: add] items length must be even number");for(let n=0;n<i;n+=2)if(e(r[n],t))return;r.push(t,n)}function n(r,t){const n=r.length;if(n%2!=0)throw new TypeError("[FlatPair: has] items length must be even number");for(let i=0;i<n;i+=2)if(e(r[i],t))return!0;return!1}function i(r,t){const n=r.length;if(n%2!=0)throw new TypeError("[FlatPair: hasByValue] items length must be even number");for(let i=1;i<n;i+=2)if(e(r[i],t))return!0;return!1}function u(r,t){const n=r.length;if(n%2!=0)throw new TypeError("[FlatPair: get] items length must be even number");for(let i=0;i<n;i+=2)if(e(r[i],t))return r[i+1]}function o(r,t){const n=r.length;if(n%2!=0)throw new TypeError("[FlatPair: getByValue] items length must be even number");for(let i=1;i<n;i+=2)if(e(r[i],t))return r[i-1]}function s(r,t){const n=r.length;if(n%2!=0)throw new TypeError("[FlatPair: remove] items length must be even number");for(let i=0;i<n;i+=2)if(e(r[i],t))return r.splice(i,2),!0;return!1}function l(r,t){const n=r.length;if(n%2!=0)throw new TypeError("[FlatPair: removeByValue] items length must be even number");for(let i=1;i<n;i+=2)if(e(r[i],t))return r.splice(i-1,2),!0;return!1}function f(e,r,t){const n=e.length;if(n%2!=0)throw new TypeError("[FlatPair: forEach] items length must be even number");for(let i=0;i<n;i+=2)i in e&&r.call(t,e[i+1],e[i],i,e)}function a(e){e.length=0}function h(e,r){const t=e.length;if(t%2!=0)throw new TypeError("[FlatPair: find] items length must be even number");for(let n=0;n<t;n+=2){if(r(e[n+1],e[n],n,e))return[e[n],e[n+1]]}}function m(e,r){const t=e.length;if(t%2!=0)throw new TypeError("[FlatPair: findIndex] items length must be even number");for(let n=0;n<t;n+=2){if(r(e[n+1],e[n],n,e))return n}return-1}class c{static from(e){if("[object Map]"!==Object.prototype.toString.call(e))throw new TypeError("[FlatPair: from] Argument must be a Map");const r=[];return e.forEach((e,t)=>r.push(t,e)),new c(r)}t=[];constructor(e){if(e.length%2!=0)throw new TypeError("[FlatPair: constructor] items length must be even number");this.t=e.slice()}get size(){return this.t.length/2}get array(){return this.t}add(e,r){return t(this.t,e,r),this}hasByValue(e){return i(this.t,e)}remove(e){return s(this.t,e)}removeByValue(e){return l(this.t,e)}get(e){return u(this.t,e)}getByValue(e){return o(this.t,e)}find(e){return h(this.t,e)}findIndex(e){return m(this.t,e)}clear(){this.t.length=0}has(e){return n(this.t,e)}forEach(e,r){f(this.t,e,r)}*keys(){for(let e=0;e<this.t.length;e+=2)yield this.t[e]}*values(){for(let e=1;e<this.t.length;e+=2)yield this.t[e]}*entries(){for(let e=0;e<this.t.length;e+=2)yield[this.t[e],this.t[e+1]]}[Symbol.iterator](){return this.entries()}}class y{add(e,r,n){t(e,r,n)}remove(e,r){return s(e,r)}get(e,r){return u(e,r)}getByValue(e,r){return o(e,r)}find(e,r){return h(e,r)}findIndex(e,r){return m(e,r)}removeByValue(e,r){return l(e,r)}forEach(e,r,t){f(e,r,t)}*keys(e){for(let r=0;r<e.length;r+=2)yield e[r]}*values(e){for(let r=1;r<e.length;r+=2)yield e[r]}*entries(e){for(let r=0;r<e.length;r+=2)yield[e[r],e[r+1]]}clear(e){e.length=0}has(e,r){return n(e,r)}hasByValue(e,r){return i(e,r)}}export{c as FlatPair,y as FlatPairOperator,t as add,a as clear,h as find,m as findIndex,f as forEach,u as get,o as getByValue,n as has,i as hasByValue,s as remove,l as removeByValue,r as size};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flat-pair",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "author": {
5
5
  "name": "Kasukabe Tsumugi",
6
6
  "email": "futami16237@gmail.com"