51375


お世話になります。  
javascriptのMapについて、value（値）からkeyを求めるより良い方法を教えてください。

現状では、for-
ofを使って検索していますが、あとから追加したもの（下の例ではid="day365"のHTMLElement）を検索しようとすると全件検索に近くなってしまい、余分に処理しているように感じます。

例）

[code]

    const days = new Map<Date, HtmlElement>();
    days.set(new Date(2018,0,1), document.getElementById("day1"));
    :
    days.set(new Date(2018,11,31), document.getElementById("day365"));
    
    const element = document.activeElement;
    for (var [key, value] of days) {
      if (value == element) {
        console.log(key);
        break;
      }
    }
    
[/code]

.Netで言うところの`days.FirstOrDefault(a => a.value == element)`のようなやり方はありますでしょうか。


CC BY-SA 4.0
2018-12-20T02:46:22.607
51371
2018-12-20T03:23:53.530
30742
question
javascript
javascriptのMapで値からKeyを求める良い方法を教えてください


残念ながら、Mapではそのような機能は提供されていません。  
そして、for-ofでやろうとすると、質問者さんのおっしゃる通り非効率的です。  
（恐らく.NETの`FirstOrDefault`も同じくらい非効率的だと思います。）  
これを実現する一つの方法は、Mapを作るときに逆向きのMapも同時に作ることです。そうすれば、valueからkeyを検索したいときはその逆向きのMapを用いることで効率的な検索が可能です。

用途にもよりますが、valueがDOMノードの場合はWeakMapを使うのが望ましいと思います。

[code]

    const days = new Map<Date, HtmlElement>();
    const daysInv = new WeakMap<HtmlElement, Date>(); // 逆向きのWeakMapを作成
    
    const date1 = new Date(2018,0,1);
    days.set(date1, document.getElementById("day1"));
    daysInv.set(document.getElementById("day1"), date1); // 逆向きの関係も保存
    :
    
    const element = document.activeElement;
    // 逆向きのMapから検索
    cont activeDate = daysInv.get(element);
    
[/code]

* * *

これは本題とは関係ありませんが、Mapのキーに`new Date(2018,0,1)`を使っているのは意図通りでしょうか？  
Mapのキーにオブジェクトを使う場合は参照として同一のオブジェクトでないと値を取り出すことができず、次のような結果となります。

[code]

    const map = new Map();
    map.set(new Date(2018,0,1), "abc");
    console.log(map.get(new Date(2018,0,1))); // undefinedが表示される
    
[/code]


CC BY-SA 4.0
2018-12-20T03:23:53.530
51375
2018-12-20T03:23:53.530
30079
51371
answer