jmg*_*net 12 dictionary date typescript angular
在我的应用程序中,我需要每个日期的对象地图。由于打字稿既有 aMap又有 aDate对象,我希望这很简单。
let map: Map<Date, MyObject> = new Map<Date, MyObject>();
Run Code Online (Sandbox Code Playgroud)
并用于set添加新的键和值对。但后来我意识到我不能get使用日期的值,除非我使用完全相同的实例Date。
我用它编写了一个单元测试:
it('Should not be a problem', () => {
let d1: Date = new Date(2019, 11, 25); // Christmas day
let d2: Date = new Date(2019, 11, 25); // Same Christmas day?
let m: Map<Date, string> = new Map<Date, string>();
m.set(d1, "X");
expect(m.get(d1)).toBe("X"); // <- This is OK.
expect(m.get(d2)).toBe("X"); // <- This test fails.
});
Run Code Online (Sandbox Code Playgroud)
为什么除非使用完全相同的实例,否则我无法从地图中获取值?
最好使用原始值(数字、字符串)作为 Map 键:
let m: Map<string, string> = new Map<string, string>();
let d1: Date = new Date(2019, 11, 25); // Christmas day
let d2: Date = new Date(2019, 11, 25); // Same Christmas day?
m.set(d1.toDateString(), "X");
console.log(d1.toDateString())
console.log(d2.toDateString())
console.log(m.get(d2.toDateString()))
Run Code Online (Sandbox Code Playgroud)
我在上述评论中提供了此类行为的链接。
这是 的核心逻辑Map,正如您所知,map 将值存储在键值对中。
为了比较密钥,密钥应始终具有相同的参考。您可能知道,字符串文字引用在许多编程语言中是相同的,因此首选使用字符串作为映射中的键。
上述行为不仅适用于date任何其他可变对象类型。
例如
let str1 = 'test';
let str2 = 'test';
str1 == str2; // true
let str1 = new String('test');
let str2 = new String('test');
str1 == str2; // false
Run Code Online (Sandbox Code Playgroud)
在获取值时map,不考虑键数据,而是搜索键的唯一标识。当您创建不可变对象时,每个对象可能具有相同的数据,但每个对象的引用将不同。因此它将被视为不同的密钥。
解决方案是使用在整个程序中可以具有相同引用的类型,例如字符串文字。
再举一个例子,
class Demo {
field: string;
constructor(f: string) {
this.field = f;
}
}
const d1 = new Demo('test');
const d2 = new Demo('test');
// both objects seems same by data, but there references are different
// hence will be treated as separate keys.
const m: Map<any, string> = new Map<any, string>();
m.set(d1, 'value1');
console.log(m.get(d1)); // value1
console.log(m.get(d2)); // undefined
Run Code Online (Sandbox Code Playgroud)