apakah ada kamus dalam javascript seperti python?

107

saya perlu membuat kamus dalam javascript seperti ini

saya tidak ingat persis notasi, tapi itu seperti:

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

apakah ada hal seperti itu di javascript?

Alex Gordon
sumber
2
Lihat pertanyaan ini: stackoverflow.com/questions/130543/…
Manoj Govindan
6
Jawaban yang Anda terima sangat salah.
Esben Skov Pedersen
@EsbenSkovPedersen Kesalahan manakah yang Anda perhatikan dalam jawaban tersebut?
Anderson Green
Saya melihatnya diedit setelah saya berkomentar. Tampaknya: hilang
Esben Skov Pedersen
2
Baca jawaban terbaru untuk ES6 Maps stackoverflow.com/a/32993723/1993919 (mengomentari alasan yang sama saat diposting)
Old Badman Grey

Jawaban:

137

Ini adalah posting lama, tapi saya pikir saya harus memberikan jawaban bergambar.

Gunakan notasi objek javascript. Seperti:

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

Dan untuk mengakses nilai:

states_dictionary.AK[0] //which is liza

atau Anda dapat menggunakan notasi objek literal javascript, di mana kuncinya tidak perlu dalam tanda kutip:

states_dictionary={ 
     CT:["alex","harry"], 
     AK:["liza","alex"], 
     TX:["fred", "harry"]
};
Kepala
sumber
12
perlu dicatat bahwa contoh pertama harus menghasilkan objek yang sama di kedua bahasa menggunakan sintaks yang persis sama kecuali penutup ';'. States_dictionary = {"CT": ["alex", "harry"], "AK": ["liza", "alex"], "TX": ["fred", "harry"]}
Denis C
Saya lebih terbiasa dengan notasi objek literal, karena Anda mengaksesnya dengan cara yang sama apa perbedaan antara keduanya?
John Demetriou
2
@JohnDemetriou perbedaan utamanya adalah kunci notasi objek javascript harus berupa string (diapit oleh tanda kutip ganda ""). Notasi objek seperti yang terlihat di JSON untuk data interchage dan terinspirasi oleh notasi objek literal; perlu dicatat bahwa JSON biasanya digunakan dalam konteks string
Chief
2
Sebenarnya, Python mengizinkan titik koma penghentian pernyataan, jadi contoh pertama benar-benar valid baik di Python maupun JavaScript
celticminstrel
Jika nilainya berasal dari pengguna, maka penggunaan harus berhati-hati Object.hasOwnProperty.call(dictionary, key)(jika tidak, pengguna dapat memasukkan nilai valueOf dan dictionary['valueOf']mengembalikan Object.valueOf()fungsi milik prototipe Objek yang mungkin bukan yang diharapkan kode Anda - potensi bug atau masalah keamanan ). Jika kuncinya bukan tipe string, maka kehati-hatian perlu dilakukan, jika tidak konversi numerik dan toString implisit akan menyebabkan masalah bagi Anda. MapJenis ES6 telah dirancang untuk menyediakan fungsionalitas yang diperluas untuk kamus.
robocat
55

Tidak ada array asosiatif nyata dalam Javascript hingga 2015 (rilis ECMAScript 6). Sejak itu Anda dapat menggunakan objek Map sebagai status Robocat. Lihat detailnya di MDN . Contoh:

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

Tanpa dukungan untuk ES6 Anda dapat mencoba menggunakan objek:

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

Namun dengan objek tidak mungkin untuk menggunakan properti array atau metode seperti array.length. Setidaknya dimungkinkan untuk mengakses "object-array" dalam for-in-loop.

Alex
sumber
3
Bagaimana dengan performanya? mencari kunci dalam waktu objek konstan?
Saher Ahwal
5
Karena o ["key"] sama dengan o.key di Javascript, performanya hampir sama. Namun kinerja tergantung pada Javascript Engine / Webbrowser. Ada banyak perbedaan di antara keduanya, terutama di versi yang lebih lama.
Alex
ECMAScript 6 mendefinisikan objek Peta resmi (yaitu "Tidak ada array asosiatif nyata dalam Javascript" sekarang salah).
robocat
19

Saya menyadari ini adalah pertanyaan lama, tetapi muncul di Google saat Anda mencari 'kamus javascript', jadi saya ingin menambahkan jawaban di atas bahwa di ECMAScript 6, Mapobjek resmi telah diperkenalkan, yaitu kamus penerapan:

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

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

Tidak seperti objek normal javascript, ini mengizinkan objek apa pun sebagai kunci:

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({});
JimmyMcHoover
sumber
Bekerja untuk saya, senang menggunakan metode ES6 yang lebih bersih. Terima kasih! Tindak lanjut, apakah kita tahu cara untuk "set massal ()", misalnya seperti python dict = { key: value)?
Joe Sadoski
10

Telah membuat kamus sederhana dalam JS di sini:

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";
        }
    }
}

Implementasi di atas sekarang dapat digunakan untuk mensimulasikan kamus sebagai:

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!"

Ini hanyalah simulasi dasar. Hal ini dapat lebih dioptimalkan dengan menerapkan algoritma waktu berjalan yang lebih baik untuk bekerja dalam kompleksitas waktu minimal O (nlogn) atau bahkan kurang. Seperti merge / quick sort pada array dan kemudian beberapa pencarian-B untuk pencarian. Saya tidak mencoba atau mencari tentang pemetaan fungsi hash di JS.

Selain itu, Kunci dan Nilai untuk objek JSdict dapat diubah menjadi variabel pribadi menjadi licik.

Semoga ini membantu!

EDIT >> Setelah menerapkan hal di atas, saya pribadi menggunakan objek JS sebagai array asosiatif yang tersedia di luar kotak.

Namun , saya ingin menyebutkan secara khusus tentang dua metode yang benar-benar terbukti membantu untuk menjadikannya pengalaman hashtable yang nyaman.

Viz: dict.hasOwnProperty (key) dan hapus dict [key]

Baca posting ini sebagai sumber yang baik tentang implementasi / penggunaan ini. Membuat kunci secara dinamis dalam array asosiatif JavaScript

Terima kasih!

Vaibhav
sumber
5

Gunakan objek JavaScript. Anda dapat mengakses propertinya seperti kunci dalam kamus. Ini adalah dasar dari JSON. Sintaksnya mirip dengan kamus Python. Lihat: JSON.org

Adam
sumber
4

Sebuah pertanyaan lama tetapi saya baru-baru ini perlu melakukan port AS3> JS, dan demi kecepatan saya menulis objek Dictionary bergaya AS3 sederhana untuk JS:

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

Jika Anda tidak tahu, kamus AS3 memungkinkan Anda menggunakan objek apa pun sebagai kunci, bukan hanya string. Mereka akan sangat berguna setelah Anda menemukan kegunaannya.

Ini tidak secepat objek asli, tetapi saya tidak menemukan masalah yang signifikan dengannya.

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
MickMalone, 1983
sumber
1
Perpustakaan yang bagus dan berguna! Saya telah menambahkan fungsi get, yang menurut saya hilang dan memperbaiki beberapa masalah sintaks kecil (titik koma hilang dll). Ini biola yang dimodifikasi: Kamus di JSFiddle
Matt
Teman kerja yang baik, tidak tahu mengapa itu tidak ada di sana!
MickMalone1983
2

Firefox 13+ menyediakan implementasi eksperimental dari mapobjek yang mirip dengan dictobjek di python. Spesifikasi di sini .

Ini hanya tersedia di firefox, tetapi terlihat lebih baik daripada menggunakan atribut a new Object(). Kutipan dari dokumentasi:

  • Objek memiliki prototipe, jadi ada kunci default di peta. Namun, ini bisa dilewati dengan menggunakan map = Object.create(null).
  • Kunci Objectare Strings, di mana mereka dapat memiliki nilai apa pun untuk a Map.
  • Anda bisa mendapatkan ukuran dengan Mapmudah sementara Anda harus melacak ukuran file secara manual Object.
mquandalle
sumber