2017-04-24 6 views
4

のキーとしてタプルを使用して、私は私のキーとしてタプルを使用した場合地図から一定の時間参照を取得する方法を理解することはできません。活字体/ Javascriptを:私のコードでは、この奇妙なバグをヒット地図

がうまくいけば、この問題を示しており、私が今使っている問題を回避するには、ちょうどそれが仕事を得るために:

let map: Map<[number, number], number> = new Map<[number, number], number>() 
    .set([0, 0], 48); 

console.log(map.get([0,0])); // prints undefined 

console.log(map.get(String([0, 0]))); // compiler: error TS2345: Argument of type 
// 'string' is not assignable to parameter of type '[number, number]'. 

//the work-around: 
map.forEach((value: number, key: [number, number]) => { 
    if(String(key) === String([0, 0])){ 
     console.log(value); // prints 48 
    } 
}) 

をコンパイルするために私が使用している:

hello.ts(transpile?) :

tsc hello.ts -target es6 

TSCバージョン2.1.6

は)(Map.getを作るために私にいくつかのことを試してみましたうまくいくことはありません。 JavaScriptで

答えて

7

(ひいては、活字体など)、どの2つの配列は、同じ配列を参照する場合(すなわち、一つの要素を変更する場合は、別の要素を変更するであろう)を除いて同じではありません。同じ要素を持つ新しい配列を作成すると、既存の配列と同じであるとは考えられません。

マップは要素を検索するときに等価性を考慮するため、配列をキーとして格納すると、キーと同じ配列参照を再度渡すだけで値を取得できます。

const map: Map<[ number, number], number> = new Map<[ number, number ], number>(); 

const a: [ number, number ] = [ 0, 0 ]; 
const b: [ number, number ] = [ 0, 0 ]; 

// a and b have the same value, but refer to different arrays so are not equal 
a === b; // = false 

map.set(a, 123); 
map.get(a); // = 123 
map.get(b); // = undefined 

このため一つの簡単な回避策は、彼らが同じ値である場合、これらは常に等しいと見なされて、キーとして文字列や数値を使用することです:

const map: Map<string, number> = new Map<string, number>(); 

const a: [ number, number ] = [ 0, 0 ]; 
const b: [ number, number ] = [ 0, 0 ]; 

const astr: string = a.join(','); // = '0,0' 
const bstr: string = b.join(','); // = '0,0' 

// astr and bstr have the same value, and are strings so they are always equal 
astr === bstr; // = true 

map.set(astr, 123); 
map.get(astr); // = 123 
map.get(bstr); // = 123 
+0

は完璧な理にかなっています。ありがとう! – ZackDeRose

2

を私がするように、これを行うために自分自身のクラスを作成します私はすべての地図方法を簡単に使うことができます:

class MyMap { 
    private map = new Map<string, number>(); 

    set(key: [number, number], value: number): this { 
     this.map.set(JSON.stringify(key), value); 
     return this; 
    } 

    get(key: [number, number]): number | undefined { 
     return this.map.get(JSON.stringify(key)); 
    } 

    clear() { 
     this.map.clear(); 
    } 

    delete(key: [number, number]): boolean { 
     return this.map.delete(JSON.stringify(key)); 
    } 

    has(key: [number, number]): boolean { 
     return this.map.has(JSON.stringify(key)); 
    } 

    get size() { 
     return this.map.size; 
    } 

    forEach(callbackfn: (value: number, key: [number, number], map: Map<[number, number], number>) => void, thisArg?: any): void { 
     this.map.forEach((value, key) => { 
      callbackfn.call(thisArg, value, JSON.parse(key), this); 
     }); 
    } 
} 

code in playground

あなたが見ることができるように、例えばforEachは自動的にあなたの代わりにあなたがして解析する必要があります。文字列の[number, number]として鍵を与えるだろう。

使用例:

let map = new MyMap(); 
map.set([1, 2], 4); 
console.log(map.get([1, 2])) // 4 

map.set([3, 4], 20); 
map.forEach((v, k) => console.log(k, v)); 
// prints: 
// [1, 2] 4 
// [3, 4] 20 
+0

http://www.collectionsjs.com/キー等価性を決定するためにcontentEqualsとcontentHashメソッドをオーバーライドすることができたともあります。 –

関連する問題