มีพจนานุกรมในจาวาสคริปต์เช่น python หรือไม่


103

ฉันต้องทำพจนานุกรมในจาวาสคริปต์เช่นนี้

ฉันจำสัญกรณ์ที่แน่นอนไม่ได้ แต่มันเหมือนกับ:

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

มีสิ่งนั้นในจาวาสคริปต์หรือไม่?


2
ดูคำถามนี้stackoverflow.com/questions/130543/…
Manoj Govindan

5
คำตอบที่คุณยอมรับผิดมาก
Esben Skov Pedersen

@EsbenSkovPedersen คุณสังเกตเห็นข้อผิดพลาดใดในคำตอบนั้น
Anderson Green

ฉันเห็นว่ามีการแก้ไขหลังจากที่ฉันแสดงความคิดเห็น ดูเหมือนว่าจะหายไป
Esben Skov Pedersen

2
อ่านคำตอบล่าสุดสำหรับ ES6 Maps stackoverflow.com/a/32993723/1993919 (แสดงความคิดเห็นด้วยเหตุผลเดียวกันกับที่โพสต์)
Old Badman Gray

คำตอบ:


133

นี่เป็นโพสต์เก่า แต่ฉันคิดว่าควรให้คำตอบที่เป็นภาพประกอบอยู่ดี

ใช้สัญกรณ์วัตถุของ javascript ชอบมาก:

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

และในการเข้าถึงค่า:

states_dictionary.AK[0] //which is liza

หรือคุณสามารถใช้สัญกรณ์ออบเจ็กต์ตัวอักษรจาวาสคริปต์โดยที่คีย์ไม่จำเป็นต้องอยู่ในเครื่องหมายคำพูด:

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

12
เป็นที่น่าสังเกตว่าตัวอย่างแรกควรให้อ็อบเจกต์เดียวกันในทั้งสองภาษาโดยใช้ไวยากรณ์เดียวกันทั้งหมดยกเว้นคำปิด ';' States_dictionary = {"CT": ["alex", "harry"], "AK": ["liza", "alex"], "TX": ["fred", "harry"]}
Denis C

ฉันคุ้นเคยกับสัญกรณ์ออบเจ็กต์ตามตัวอักษรมากกว่าเนื่องจากคุณเข้าถึงพวกเขาในลักษณะเดียวกันความแตกต่างระหว่างทั้งสองคืออะไร?
John Demetriou

2
@JohnDemetriou ข้อแตกต่างที่สำคัญคือคีย์สัญกรณ์วัตถุจาวาสคริปต์ต้องเป็นสตริง (อยู่ในเครื่องหมายคำพูดคู่ "") สัญกรณ์ออบเจ็กต์ดังที่เห็นใน JSON สำหรับการคั่นระหว่างข้อมูลและได้รับแรงบันดาลใจจากสัญกรณ์วัตถุตามตัวอักษร เป็นที่น่าสังเกตว่าโดยทั่วไป JSON จะใช้ในบริบทสตริง
หัวหน้า

2
อันที่จริง Python อนุญาตให้ใช้เครื่องหมายอัฒภาคยุติคำสั่งดังนั้นตัวอย่างแรกจึงใช้ได้อย่างสมบูรณ์ทั้งใน Python และ JavaScript
celticminstrel

หากค่ามาจากผู้ใช้จำเป็นต้องใช้ความระมัดระวังในการใช้งานObject.hasOwnProperty.call(dictionary, key)(มิฉะนั้นผู้ใช้สามารถป้อนค่าvalueOfและdictionary['valueOf']ส่งคืนObject.valueOf()ฟังก์ชันที่เป็นของต้นแบบวัตถุซึ่งอาจไม่เป็นไปตามที่รหัสของคุณคาดหวัง - อาจมีข้อบกพร่องหรือปัญหาด้านความปลอดภัย ). หากคีย์ไม่ใช่ประเภทสตริงต้องใช้ความระมัดระวังมิฉะนั้นการแปลงตัวเลขโดยนัยและ toString จะทำให้คุณมีปัญหา MapประเภทES6 ได้รับการออกแบบมาเพื่อให้มีฟังก์ชันเพิ่มเติมสำหรับพจนานุกรม
robocat

54

ไม่มีอาร์เรย์ที่เชื่อมโยงจริงใน Javascript จนถึงปี 2015 (รุ่น ECMAScript 6) ตั้งแต่นั้นมาคุณสามารถใช้วัตถุแผนที่เป็นสถานะของ Robocat เงยหน้าขึ้นมองรายละเอียด 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 อย่างน้อยก็สามารถเข้าถึง "object-array" แบบ for-in-loop


3
แล้วประสิทธิภาพล่ะ? กำลังมองหากุญแจในเวลาคงที่ของวัตถุหรือไม่?
Saher Ahwal

5
เนื่องจาก o ["key"] เทียบเท่ากับ o.key ใน Javascript ประสิทธิภาพจึงเกือบจะเท่ากัน อย่างไรก็ตามประสิทธิภาพขึ้นอยู่กับ Javascript Engine / Webbrowser มีความแตกต่างกันค่อนข้างมากโดยเฉพาะในเวอร์ชันเก่า
Alex

ECMAScript 6 กำหนดอ็อบเจ็กต์แผนที่อย่างเป็นทางการ (เช่น "ไม่มีอาร์เรย์ที่เชื่อมโยงจริงใน Javascript" ไม่ถูกต้อง)
robocat

18

ฉันรู้ว่านี่เป็นคำถามเก่า แต่จะปรากฏขึ้นใน 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 ที่สะอาดกว่า ขอบคุณ! ติดตามผลเรารู้วิธีใด ๆ ในการ "Bulk set ()" เช่น python 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-search สำหรับการค้นหา ฉันไม่ได้ลองหรือค้นหาเกี่ยวกับการแมปฟังก์ชันแฮชใน JS

นอกจากนี้คีย์และค่าสำหรับ JSdict obj ยังสามารถเปลี่ยนเป็นตัวแปรส่วนตัวเพื่อส่อเสียดได้

หวังว่านี่จะช่วยได้!

แก้ไข >> หลังจากใช้งานข้างต้นฉันใช้ออบเจ็กต์ JS เป็นการส่วนตัวเป็นอาร์เรย์ที่เชื่อมโยงซึ่งพร้อมใช้งานนอกกรอบ

อย่างไรก็ตามฉันต้องการกล่าวถึงเป็นพิเศษเกี่ยวกับวิธีการสองวิธีที่พิสูจน์แล้วว่ามีประโยชน์จริง ๆ เพื่อทำให้เป็นประสบการณ์แฮชแท็กที่สะดวก

เช่น: dict.hasOwnProperty (คีย์) และ ลบ dict [คีย์]

อ่านโพสต์นี้เป็นแหล่งข้อมูลที่ดีเกี่ยวกับการใช้งาน / การใช้งานนี้ สร้างคีย์แบบไดนามิกในอาร์เรย์ที่เชื่อมโยงของ JavaScript

ขอบคุณ!


5

ใช้วัตถุ JavaScript คุณสามารถเข้าถึงคุณสมบัติเช่นคีย์ในพจนานุกรม นี่คือรากฐานของ JSON ไวยากรณ์คล้ายกับพจนานุกรม Python ดู: JSON.org


4

คำถามเก่า แต่ฉันเพิ่งต้องทำพอร์ต AS3> JS และเพื่อความรวดเร็วฉันจึงเขียนออบเจ็กต์พจนานุกรมสไตล์ AS3 แบบธรรมดาสำหรับ JS:

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
Matt

เพื่อนร่วมงานที่ดีไม่รู้ทำไมไม่อยู่ที่นั่น!
MickMalone1983

2

Firefox 13+ ให้การทดลองใช้งานmapวัตถุที่คล้ายกับdictวัตถุใน python ข้อมูลจำเพาะที่นี่

ใช้ได้เฉพาะใน firefox แต่ดูดีกว่าการใช้คุณลักษณะของไฟล์new Object(). อ้างอิงจากเอกสาร:

  • วัตถุมีต้นแบบดังนั้นจึงมีคีย์เริ่มต้นในแผนที่ อย่างไรก็ตามสิ่งนี้สามารถข้ามได้โดยใช้map = Object.create(null).
  • คีย์ของObjectคือStringsที่ซึ่งสามารถเป็นค่าใดก็ได้สำหรับไฟล์Map.
  • คุณสามารถรับขนาดMapได้อย่างง่ายดายในขณะที่คุณต้องติดตามขนาดของObjectไฟล์.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.