1
- import { InternalNamePath } from '../interface' ;
2
- import { matchNamePath } from './valueUtil' ;
1
+ import type { InternalNamePath } from '../interface' ;
3
2
4
3
interface KV < T > {
5
4
key : InternalNamePath ;
6
5
value : T ;
7
6
}
8
7
8
+ const SPLIT = '__@field_split__' ;
9
+
10
+ /**
11
+ * Convert name path into string to fast the fetch speed of Map.
12
+ */
13
+ function normalize ( namePath : InternalNamePath ) : string {
14
+ return (
15
+ namePath
16
+ . map ( cell => `${ typeof cell } :${ cell } ` )
17
+ // Magic split
18
+ . join ( SPLIT )
19
+ ) ;
20
+ }
21
+
9
22
/**
10
23
* NameMap like a `Map` but accepts `string[]` as key.
11
24
*/
12
25
class NameMap < T > {
13
- private list : KV < T > [ ] = [ ] ;
26
+ private kvs = new Map < string , T > ( ) ;
14
27
15
28
public set ( key : InternalNamePath , value : T ) {
16
- const index = this . list . findIndex ( item => matchNamePath ( item . key , key ) ) ;
17
- if ( index !== - 1 ) {
18
- this . list [ index ] . value = value ;
19
- } else {
20
- this . list . push ( {
21
- key,
22
- value,
23
- } ) ;
24
- }
29
+ this . kvs . set ( normalize ( key ) , value ) ;
25
30
}
26
31
27
32
public get ( key : InternalNamePath ) {
28
- const result = this . list . find ( item => matchNamePath ( item . key , key ) ) ;
29
- return result && result . value ;
33
+ return this . kvs . get ( normalize ( key ) ) ;
30
34
}
31
35
32
36
public update ( key : InternalNamePath , updater : ( origin : T ) => T | null ) {
@@ -41,15 +45,26 @@ class NameMap<T> {
41
45
}
42
46
43
47
public delete ( key : InternalNamePath ) {
44
- this . list = this . list . filter ( item => ! matchNamePath ( item . key , key ) ) ;
48
+ this . kvs . delete ( normalize ( key ) ) ;
45
49
}
46
50
51
+ // Since we only use this in test, let simply realize this
47
52
public map < U > ( callback : ( kv : KV < T > ) => U ) {
48
- return this . list . map ( callback ) ;
53
+ return [ ...this . kvs . entries ( ) ] . map ( ( [ key , value ] ) => {
54
+ const cells = key . split ( SPLIT ) ;
55
+
56
+ return callback ( {
57
+ key : cells . map ( cell => {
58
+ const [ , type , unit ] = cell . match ( / ^ ( [ ^ : ] * ) : ( .* ) $ / ) ;
59
+ return type === 'number' ? Number ( unit ) : unit ;
60
+ } ) ,
61
+ value,
62
+ } ) ;
63
+ } ) ;
49
64
}
50
65
51
- public toJSON ( ) : { [ name : string ] : T } {
52
- const json : { [ name : string ] : T } = { } ;
66
+ public toJSON ( ) : Record < string , T > {
67
+ const json : Record < string , T > = { } ;
53
68
this . map ( ( { key, value } ) => {
54
69
json [ key . join ( '.' ) ] = value ;
55
70
return null ;
0 commit comments