【问题标题】:are there dictionaries in javascript like python?javascript中是否有像python这样的字典?
【发布时间】:2011-04-03 07:27:45
【问题描述】:

我需要像这样用javascript制作字典

我不记得确切的符号,但大概是这样的:

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

javascript中有这样的东西吗?

【问题讨论】:

标签: javascript python


【解决方案1】:

这是一篇旧帖子,但我认为无论如何我应该提供一个图解答案。

使用 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"]
};

【讨论】:

  • 值得注意的是,第一个示例应该在两种语言中使用完全相同的语法生成相同的对象,但结束符 ';' 除外。 states_dictionary={ "CT":["alex","harry"], "AK":["liza","alex"], "TX":["fred", "harry"] }
  • 我更习惯使用字面量对象表示法,因为你访问它们的方式相同,两者有什么区别?
  • @JohnDemetriou 的主要区别是 javascript 对象表示法键必须是字符串(用双引号 " " 括起来)。对象表示法在 JSON 中用于数据交换,并受到文字对象表示法的启发;值得注意的是,JSON 通常用于字符串上下文
  • 实际上,Python 允许语句终止分号,所以第一个例子在 Python 和 JavaScript 中都是完全有效的
  • 如果值来自用户,则需要注意使用Object.hasOwnProperty.call(dictionary, key)(否则用户可以输入值valueOfdictionary['valueOf']返回Object.valueOf() 属于 Object 原型的函数,这可能不是您的代码所期望的 - 潜在的错误或安全问题)。如果键不是字符串类型,则需要小心,否则隐式数字和 toString 转换会给您带来问题。 ES6 Map 类型旨在为字典提供扩展功能。
【解决方案2】:

在 2015 年(ECMAScript 6 发布)之前,Javascript 中没有真正的关联数组。从那时起,您可以将 Map 对象用作 Robocat 状态。 Look up the details in 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 中访问“对象数组”。

【讨论】:

  • 性能怎么样?是否在对象常量时间内查找键?
  • 由于 o["key"] 等价于 Javascript 中的 o.key,因此性能几乎相同。然而,性能取决于 Javascript 引擎/网络浏览器。这些之间有很多差异,尤其是在旧版本中。
  • ECMAScript 6 定义了一个官方 Map 对象(即“Javascript 中没有真正的关联数组”现在是不正确的)。
【解决方案3】:

我意识到这是一个老问题,但是当您搜索“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 方法。谢谢!跟进,我们知道“批量设置()”的任何方法,例如像蟒蛇dict = { key: value)?
【解决方案4】:

在这里用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 的 Key 和 Value 可以转为私有变量来偷偷摸摸。

希望这会有所帮助!

编辑>> 在实现了上述之后,我个人将 JS 对象用作开箱即用的关联数组。

然而,我想特别提到两种方法,它们实际上被证明有助于使其成为一种方便的哈希表体验。

即:dict.hasOwnProperty(key) 删除dict[key]

阅读这篇文章作为有关此实现/使用的良好资源。 Dynamically creating keys in JavaScript associative array

谢谢!

【讨论】:

    【解决方案5】:

    使用 JavaScript 对象。您可以访问它们的属性,例如字典中的键。这是 JSON 的基础。语法类似于 Python 字典。见:JSON.org

    【讨论】:

    • “小心”!像“watch”这样的对象原型方法可以这样咬你。即使你没有这些,你至少会有“constructor”。
    【解决方案6】:

    一个老问题,但我最近需要做一个 AS3>JS 移植,为了速度,我为 JS 写了一个简单的 AS3 风格的 Dictionary 对象:

    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
    

    【讨论】:

    • 好用的库!我添加了一个我认为缺少的 get 函数并修复了一些小的语法问题(缺少分号等)。这是修改后的小提琴:Dictionary in JSFiddle
    • 干得好伙伴,不知道为什么不在那里!
    【解决方案7】:

    Firefox 13+ 提供了 map 对象的实验性实现,类似于 python 中的 dict 对象。 Specifications here.

    它只在 Firefox 中可用,但它看起来比使用 new Object() 的属性更好。来自文档的引用:

    • 一个对象有一个原型,所以映射中有默认键。但是,可以使用 map = Object.create(null) 绕过此问题。
    • Object 的键是 Strings,它们可以是 Map 的任何值。
    • 您可以轻松获取Map 的大小,而您必须手动跟踪Object 的大小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-30
      • 2015-09-09
      • 2015-03-20
      • 2016-12-22
      • 2021-01-15
      • 2021-03-28
      • 2012-10-14
      • 1970-01-01
      相关资源
      最近更新 更多