我在TypeScript中使用Map字典,并且我希望有get属性并具有不区分大小写的属性。我该如何工作?
let envVariables = new Map<string, string>();
envVariables.set('OS', 'Windows_NT');
envVariables.set('USERNAME', 'SYSTEM');
if (this.envVariables.has('UserName')) {
// this should work with case insensitive search
}
Run Code Online (Sandbox Code Playgroud)
在C#中,Dictionary构造函数只需要StringComparer.OrdinalIgnoreCase,然后字典将不区分大小写。
这是我使用 TypeScript 创建的“真正的”不区分大小写映射的变体:它包含一个存储原始密钥的私有映射。
export class CaseInsensitiveMap<TKey, TVal> extends Map<TKey, TVal> {
private keysMap = new Map<TKey, TKey>();
constructor(iterable?: Iterable<[TKey, TVal]>){
super();
if (iterable) {
for (const [key, value] of iterable) {
this.set(key, value);
}
}
}
set(key: TKey, value: TVal): this {
const keyLowerCase = typeof key === 'string'
? key.toLowerCase() as any as TKey
: key;
this.keysMap.set(keyLowerCase, key);
return super.set(keyLowerCase, value);
}
get(key: TKey): TVal | undefined {
return typeof key === 'string'
? super.get(key.toLowerCase() as any as TKey)
: super.get(key);
}
has(key: TKey): boolean {
return typeof key === 'string'
? super.has(key.toLowerCase() as any as TKey)
: super.has(key);
}
delete(key: TKey): boolean {
const keyLowerCase = typeof key === 'string'
? key.toLowerCase() as any as TKey
: key;
this.keysMap.delete(keyLowerCase);
return super.delete(keyLowerCase);
}
clear(): void {
this.keysMap.clear();
super.clear();
}
keys(): IterableIterator<TKey> {
return this.keysMap.values();
}
*entries(): IterableIterator<[TKey, TVal]> {
const keys = this.keysMap.values();
const values = super.values();
for (let i = 0; i < super.size; i++) {
yield [keys.next().value, values.next().value];
}
}
forEach(callbackfn: (value: TVal, key: TKey, map: Map<TKey, TVal>) => void): void {
const keys = this.keysMap.values();
const values = super.values();
for (let i = 0; i < super.size; i++) {
callbackfn(values.next().value, keys.next().value, this);
}
}
[Symbol.iterator](): IterableIterator<[TKey, TVal]> {
return this.entries();
}
}
Run Code Online (Sandbox Code Playgroud)
Map不支持此行为。可以扩展它以便以不区分大小写的方式存储和查找密钥。由于Map内部set在构造上使用,因此这是唯一需要增强的方法。
在带有es5target的TypeScript中扩展时,应以特殊方式对待本机类。可以这样完成:
interface CaseInsensitiveMap<T, U> extends Map<T, U> {}
class CaseInsensitiveMap<T, U> {
constructor(entries?: Array<[T, U]> | Iterable<[T, U]>) {
return Reflect.construct(Map, arguments, CaseInsensitiveMap);
}
set (key: T, value: U): this {
if (typeof key === 'string') {
key = <T><any>key.toLowerCase();
}
return Map.prototype.set.call(this, key, value);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
773 次 |
| 最近记录: |