Pythonのようなjavascriptの辞書はありますか?


97

私はこのようなJavaScriptで辞書を作る必要があります

私は正確な表記を覚えていませんが、それは次のようなものでした:

states_dictionary={ CT=[alex,harry], AK=[liza,alex], TX=[fred, harry] ........ }

JavaScriptにそのようなものはありますか?


2
この質問を参照してください:stackoverflow.com/questions/130543/...
Manojさんゴヴィンダン

5
あなたが受け入れた答えは非常に間違っています。
Esben Skov Pedersen、2012

@EsbenSkovPedersenその回答でどのエラーに気付きましたか?
アンダーソングリーン

コメントした後で編集されているのがわかります。見たところ:行方不明だった
エスベンスコフペデルセン2013

2
ES6マップの読む最新答えstackoverflow.com/a/32993723/1993919(それが掲載されたのと同じ理由でコメント)
旧Badmanでグレー

回答:


128

これは古い投稿ですが、とにかく図解の答えを出すべきだと思いました。

JavaScriptのオブジェクト表記を使用します。そのようです:

states_dictionary={ 
     "CT":["alex","harry"], 
     "AK":["liza","alex"], 
     "TX":["fred", "harry"]
};

そして値にアクセスするには:

states_dictionary.AK[0] //which is liza

または、JavaScriptリテラルオブジェクト表記を使用して、キーを引用符で囲む必要がないようにすることもできます。

states_dictionary={ 
     CT:["alex","harry"], 
     AK:["liza","alex"], 
     TX:["fred", "harry"]
};

11
最初の例では、両端の「;」を除いてまったく同じ構文を使用して、両方の言語で同じオブジェクトを生成する必要があることに注意してください。states_dictionary = {"CT":["alex"、 "harry"]、 "AK":["liza"、 "alex"]、 "TX":["fred"、 "harry"]}
デニスC

あなたは同じようにそれらにアクセスするので、私はリテラルオブジェクト表記に慣れていますか?2つの違いは何ですか?
John Demetriou

2
@JohnDemetriouの主な違いは、JavaScriptオブジェクト表記キーは文字列(二重引用符 ""で囲む)でなければならないことです。オブジェクト表記は、データのインターチェンジについてJSONで見られるものであり、リテラルオブジェクト表記に触発されました。JSONは通常、文字列のコンテキストで使用されていることは注目に値する
チーフ

2
実際、Pythonではステートメント終了セミコロンが許可されているため、最初の例はPythonとJavaScriptの両方で完全に有効です
celticminstrel

値がユーザーからのものである場合は、使用に注意する必要がありますObject.hasOwnProperty.call(dictionary, key)(そうでない場合、ユーザーはvalueOfの値を入力して、コードが期待するものとは異なるObjectプロトタイプに属する関数をdictionary['valueOf']返すObject.valueOf()可能性があります-潜在的なバグまたはセキュリティの問題)。キーが文字列型でない場合は注意が必要です。それ以外の場合は、暗黙的な数値およびtoString変換によって問題が発生します。ES6 Mapタイプは、辞書に拡張機能を提供するように設計されています。
robocat 2016年

48

2015年(ECMAScript 6のリリース)まで、Javascriptには実際の連想配列はありませんでした。それ以降、Robocatの状態としてMapオブジェクトを使用できます。MDNで詳細を調べてください。例:

let map = new Map();
map.set('key', {'value1', 'value2'});
let values = map.get('key');

ES6のサポートがなければ、オブジェクトを使用してみることができます。

var x = new Object();
x["Key"] = "Value";

ただし、オブジェクトでは、array.lengthなどの一般的な配列プロパティやメソッドを使用することはできません。少なくともfor-in-loopで「オブジェクト配列」にアクセスすることは可能です。


3
パフォーマンスはどうですか?オブジェクトのキーを一定時間検索していますか?
Saher Ahwal、2011年

5
o ["key"]はJavaScriptのo.keyと同等であるため、パフォーマンスはほぼ同じです。ただし、パフォーマンスはJavaScriptエンジン/ Webブラウザーに依存します。特に古いバージョンでは、これらの間にはかなり多くの違いがあります。
Alex

ECMAScript 6は公式のMapオブジェクトを定義します(つまり、「JavaScriptには実際の連想配列はありません」は正しくありません)。
robocat 2016年

18

これは古い質問ですが、「javascript辞書」を検索するとGoogleにポップアップ表示されるので、ECMAScript 6ではMap辞書である公式オブジェクトが導入されたことを上記の回答に追加したいと思います実装:

var dict = new Map();
dict.set("foo", "bar");

//returns "bar"
dict.get("foo");

JavaScriptの通常のオブジェクトとは異なり、任意のオブジェクトをキーとして使用できます。

var foo = {};
var bar = {};
var dict = new Map();
dict.set(foo, "Foo");
dict.set(bar, "Bar");

//returns "Bar"
dict.get(bar);

//returns "Foo"
dict.get(foo);

//returns undefined, as {} !== foo and {} !== bar
dict.get({});

クリーンなES6メソッドを使用すると便利です。ありがとうございました!フォローアップ、たとえばpythonのように、「バルクset()」への方法を知っていますdict = { key: value)か?
Joe Sadoski

10

ここでJSで簡単な辞書を作成しました:

function JSdict() {
    this.Keys = [];
    this.Values = [];
}

// Check if dictionary extensions aren't implemented yet.
// Returns value of a key
if (!JSdict.prototype.getVal) {
    JSdict.prototype.getVal = function (key) {
        if (key == null) {
            return "Key cannot be null";
        }
        for (var i = 0; i < this.Keys.length; i++) {
            if (this.Keys[i] == key) {
                return this.Values[i];
            }
        }
        return "Key not found!";
    }
}


// Check if dictionary extensions aren't implemented yet.
// Updates value of a key
if (!JSdict.prototype.update) {
    JSdict.prototype.update = function (key, val) {
        if (key == null || val == null) {
            return "Key or Value cannot be null";
        }
        // Verify dict integrity before each operation
        if (keysLength != valsLength) {
            return "Dictionary inconsistent. Keys length don't match values!";
        }
        var keysLength = this.Keys.length;
        var valsLength = this.Values.length;
        var flag = false;
        for (var i = 0; i < keysLength; i++) {
            if (this.Keys[i] == key) {
                this.Values[i] = val;
                flag = true;
                break;
            }
        }
        if (!flag) {
            return "Key does not exist";
        }
    }
}



// Check if dictionary extensions aren't implemented yet.
// Adds a unique key value pair
if (!JSdict.prototype.add) {
    JSdict.prototype.add = function (key, val) {
        // Allow only strings or numbers as keys
        if (typeof (key) == "number" || typeof (key) == "string") {
            if (key == null || val == null) {
                return "Key or Value cannot be null";
            }
            if (keysLength != valsLength) {
                return "Dictionary inconsistent. Keys length don't match values!";
            }
            var keysLength = this.Keys.length;
            var valsLength = this.Values.length;
            for (var i = 0; i < keysLength; i++) {
                if (this.Keys[i] == key) {
                    return "Duplicate keys not allowed!";
                }
            }
            this.Keys.push(key);
            this.Values.push(val);
        }
        else {
            return "Only number or string can be key!";
        }
    }
}

// Check if dictionary extensions aren't implemented yet.
// Removes a key value pair
if (!JSdict.prototype.remove) {
    JSdict.prototype.remove = function (key) {
        if (key == null) {
            return "Key cannot be null";
        }
        if (keysLength != valsLength) {
            return "Dictionary inconsistent. Keys length don't match values!";
        }
        var keysLength = this.Keys.length;
        var valsLength = this.Values.length;
        var flag = false;
        for (var i = 0; i < keysLength; i++) {
            if (this.Keys[i] == key) {
                this.Keys.shift(key);
                this.Values.shift(this.Values[i]);
                flag = true;
                break;
            }
        }
        if (!flag) {
            return "Key does not exist";
        }
    }
}

上記の実装を使用して、次のように辞書をシミュレートできます。

var dict = new JSdict();

dict.add(1, "one")

dict.add(1, "one more")
"Duplicate keys not allowed!"

dict.getVal(1)
"one"

dict.update(1, "onne")

dict.getVal(1)
"onne"

dict.remove(1)

dict.getVal(1)
"Key not found!"

これは単なる基本的なシミュレーションです。これは、より良い実行時間アルゴリズムを実装して、少なくともO(nlogn)時間以下の複雑さで機能するようにさらに最適化できます。配列のマージ/クイックソートのように、次にルックアップのB検索を行います。JSでのハッシュ関数のマッピングについて、試したり検索したりしませんでした。

また、JSdictオブジェクトのキーと値をプライベート変数に変換して、こっそりさせることができます。

お役に立てれば!

編集>>上記を実装した後、JSオブジェクトを連想配列として個人的に使用しました。

ただし、便利なハッシュテーブルエクスペリエンスにするために実際に役立つことが判明した2つのメソッドについて、特別に触れておきます。

Viz:dict.hasOwnProperty(key) dict [key] 削除

この実装/使用法に関する優れたリソースとしてこの投稿を読んでください。 JavaScript連想配列で動的にキーを作成する

ありがとう!


5

JavaScriptオブジェクトを使用します。辞書のキーなどのプロパティにアクセスできます。これがJSONの基礎です。構文はPython辞書に似ています。参照:JSON.org


4

古い質問ですが、最近AS3> JSの移植を行う必要がありました。速度を上げるために、JS用の簡単なAS3スタイルのディクショナリオブジェクトを作成しました。

http://jsfiddle.net/MickMalone1983/VEpFf/2/

知らなかった場合は、AS3辞書を使用すると、文字列だけでなく、任意のオブジェクトをキーとして使用できます。用途が分かればとても重宝します。

ネイティブオブジェクトほど高速ではありませんが、その点で大きな問題は見つかりませんでした。

API:

//Constructor
var dict = new Dict(overwrite:Boolean);

//If overwrite, allows over-writing of duplicate keys,
//otherwise, will not add duplicate keys to dictionary.

dict.put(key, value);//Add a pair
dict.get(key);//Get value from key
dict.remove(key);//Remove pair by key
dict.clearAll(value);//Remove all pairs with this value
dict.iterate(function(key, value){//Send all pairs as arguments to this function:
    console.log(key+' is key for '+value);
});


dict.get(key);//Get value from key

1
素敵で便利なライブラリ!get関数を追加しましたが、不足していると思い、いくつかの軽微な構文問題(セミコロンがないなど)を修正しました。修正されたフィドルは次のとおりです。JSFiddleのディクショナリー
マット

いい仕事仲間、なぜそれがそこになかったのか知らない!
MickMalone1983

2

Firefox 13以降では、Pythonのmapオブジェクトに類似したdictオブジェクトの実験的な実装が提供されています。仕様はこちら

これはFirefoxでのみ使用できますが、の属性を使用するよりも見栄えがしますnew Object()。ドキュメントからの引用:

  • オブジェクトにはプロトタイプがあるため、マップにはデフォルトのキーがあります。ただし、これはを使用してバイパスできますmap = Object.create(null)
  • のキーはでObjectありStrings、の任意の値にすることができますMap
  • のサイズMapを手動で追跡する必要がある一方で、のサイズを簡単に取得できますObject
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.