2017-02-14 7 views
-1

ライブラリを使用しない場合を除き、Python's defaultdict in Javascriptのようなものが必要です。私はこれが純粋なJavascriptに存在しないことを理解しています。しかし、後で望ましくないコーナーケースを打ち負かすことのない妥当な量のコードで、そのような型を定義する方法はありますか(大規模なライブラリをソースファイルにコピー&ペーストするだけでなく)ですか?ライブラリなしのJavascript defaultdict

は、私は次のコードを記述することができるようにしたい:

var m = defaultdict(function() { return [] }); 
m["asdf"].push(0); 
m["qwer"].push("foo"); 
Object.keys(m).forEach(function(value, key) { 
    // Should give me "asdf" -> [0] and "qwer" -> ["foo"] 
}); 

が、私はこれは、Firefox、クロム、サファリ、理想的にエッジの最近のバージョンで作業する必要があります。

また、私はではありません。可能な限りライブラリを使用したいと考えています。依存関係を最小限に抑える方法でこれを行う方法が必要です。前回の回答が動作しない理由を

理由:

This answerは、ライブラリを使用していますので、それは私の最初の基準を失敗しました。また、提供するdefaultdictは、実際にはJavascriptオブジェクトのように動作しません。私はPythonをJavascriptで書こうとは考えていませんが、私はJavascriptコードをあまり苦労させたくありません。

This answerは、getを定義しています。ただし、これを使用してコレクションタイプ(リストのマップなど)にはdefaultdictを定義することはできません。そして私はこのアプローチがObject.keysでもうまくいくとは思わない。

This answer言い換えると、後で悪いコーナーケースにつながる穴ができないようにするために実装する方法がいくつあるかはわかりません。 を書くProxyメソッドのは確かに痛みのようですが、何かメソッドをスキップすると、ハンドラを実装していないものを使用しようとすると、苦しいバグが発生する可能性があります。 (ボーナスに関する質問:このような穴を避けるために実装する必要があるプロキシメソッドの最小限のセットは何ですか?)一方、提案されているgetterアプローチは標準オブジェクトの構文に従わず、 Object.keysのようなことをしてください。

+0

が、何を考えることが役に立つかもしれない:プロキシを使用すると、上書きする必要があるすべては自動的に非既存のプロパティを作成する必要がありますgetトラップで、実際には非常に簡単ですあなたは、あなたが(別の言語から)慣れ親しんだ方法で問題を解決しようとするのではなく、これで達成しようとしています。 –

+0

どのように[定義されたゲッターとセッター](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters)が不足していますか? – Hamms

+0

@AlexSzabóこれは、典型的なネストされたマップパターンの苦痛を少なくするための試みです。私。私は概念的にマップ 'a - > b - > c'で、' var x = defaultdict(function(){return {};})のようなコードを書くことができます。次のレベルのデータ構造が存在する場合、各レベルでチェックする定型文はありません。x ["a"] ["b"] = 1;私が提案しているよりも良い方法があれば教えてください。 –

答えて

2

あなたは本当にproxyを探しているようです。あなたが言及している最新のブラウザーで利用でき、ライブラリではなく、標準のオブジェクト構文を維持できる唯一のテクノロジーです。これは、あなたの質問に答えることを意図していない

function defaultDict(createValue) { 
    return new Proxy(Object.create(null), { 
     get(storage, property) { 
      if (!(property in storage)) 
       storage[property] = createValue(property); 
      return storage[property]; 
     } 
    }); 
} 

var m = defaultdict(function() { return [] }); 
m["asdf"].push(0); 
m["qwer"].push("foo"); 
Object.keys(m).forEach(console.log); 
関連する問題