existem dicionários em javascript como python?

98

eu preciso fazer um dicionário em javascript como este

não me lembro da notação exata, mas era algo como:

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

existe tal coisa em javascript?

eu--''''''---------''''''''''''
fonte
2
Veja esta pergunta: stackoverflow.com/questions/130543/…
Manoj Govindan
5
A resposta que você aceitou está muito errada.
Esben Skov Pedersen
@EsbenSkovPedersen Quais erros você notou nessa resposta?
Anderson Green,
Vejo que é editado depois que comentei. Parece: estava faltando
Esben Skov Pedersen
2
Leia a resposta mais recente para ES6 Maps stackoverflow.com/a/32993723/1993919 (comentando pelo mesmo motivo que foi postado)
Old Badman Gray

Respostas:

129

Esta é uma postagem antiga, mas achei que deveria fornecer uma resposta ilustrada de qualquer maneira.

Use a notação de objeto do javascript. Igual a:

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

E para acessar os valores:

states_dictionary.AK[0] //which is liza

ou você pode usar a notação de objeto literal javascript, em que as chaves não precisam estar entre aspas:

states_dictionary={ 
     CT:["alex","harry"], 
     AK:["liza","alex"], 
     TX:["fred", "harry"]
};
Chefe
fonte
11
é importante notar que o primeiro exemplo deve produzir o mesmo objeto em ambas as linguagens usando exatamente a mesma sintaxe, exceto o fechamento ';'. states_dictionary = {"CT": ["alex", "harry"], "AK": ["liza", "alex"], "TX": ["fred", "harry"]}
Denis C
Estou mais acostumado com a notação de objeto literal, já que você os acessa da mesma forma, qual a diferença entre os dois?
John Demetriou de
2
@JohnDemetriou a principal diferença é que as chaves de notação de objeto javascript devem ser strings (entre aspas duplas ""). A notação de objeto é como vista em JSON para interchage de dados e foi inspirada pela notação de objeto literal; É importante notar que JSON é geralmente usado no contexto de string
Chief
2
Na verdade, Python permite ponto-e-vírgulas de terminação de instrução, então o primeiro exemplo é totalmente válido tanto em Python quanto em JavaScript
celticminstrel
Se o valor vier do usuário, deve-se tomar cuidado ao usá-lo Object.hasOwnProperty.call(dictionary, key)(caso contrário, o usuário pode inserir um valor de valueOf e dictionary['valueOf']retornar a Object.valueOf()função pertencente ao protótipo do objeto que provavelmente não é o que seu código esperaria - bug potencial ou problema de segurança ) Se a chave não for um tipo de string, é necessário tomar cuidado, caso contrário, as conversões numérica e toString implícitas causarão problemas. O Maptipo ES6 foi projetado para fornecer funcionalidade estendida para dicionários.
robocat
48

Não havia matrizes associativas reais em Javascript até 2015 (lançamento do ECMAScript 6). Desde então, você pode usar o objeto Map como estados Robocat. Procure os detalhes no MDN . Exemplo:

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

Sem suporte para ES6, você pode tentar usar objetos:

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

No entanto, com objetos não é possível usar propriedades ou métodos de array típicos como array.length. Pelo menos é possível acessar o "objeto-array" em um for-in-loop.

Alex
fonte
3
E quanto ao desempenho? está procurando uma chave em um tempo constante de objeto?
Saher Ahwal,
5
Como o ["key"] é equivalente a o.key em Javascript, o desempenho é quase o mesmo. No entanto, o desempenho depende do Javascript Engine / Webbrowser. Existem muitas diferenças entre eles, especialmente nas versões mais antigas.
Alex
ECMAScript 6 define um objeto de mapa oficial (ou seja, "Não há matrizes associativas reais em Javascript" agora está incorreto).
robocat
18

Sei que essa é uma pergunta antiga, mas ela aparece no Google quando você pesquisa por 'dicionários de javascript', então gostaria de acrescentar às respostas acima que no ECMAScript 6, o Mapobjeto oficial foi introduzido, que é um dicionário implementação:

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

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

Ao contrário dos objetos normais do javascript, ele permite qualquer objeto como uma chave:

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
fonte
Funciona para mim, bom usar um método ES6 mais limpo. Obrigado! Acompanhamento, de nós sabemos alguma maneira de "bulk set ()", por exemplo, como python dict = { key: value)?
Joe Sadoski
10

Criei um dicionário simples em JS aqui:

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

A implementação acima agora pode ser usada para simular um dicionário como:

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

Esta é apenas uma simulação básica. Ele pode ser otimizado ainda mais através da implementação de um algoritmo de tempo de execução melhor para trabalhar em complexidade de tempo pelo menos O (nlogn) ou até menos. Como mesclar / classificação rápida em arrays e, em seguida, algumas pesquisas B para pesquisas. Não tentei ou pesquisei sobre o mapeamento de uma função hash em JS.

Além disso, a chave e o valor para o objeto JSdict podem ser transformados em variáveis ​​privadas para serem sorrateiros.

Espero que isto ajude!

EDITAR >> Depois de implementar o acima, eu pessoalmente usei os objetos JS como arrays associativos que estão disponíveis prontos para uso.

No entanto , gostaria de fazer uma menção especial sobre dois métodos que realmente se mostraram úteis para torná-lo uma experiência hashtable conveniente.

Viz: dict.hasOwnProperty (key) e delete dict [key]

Leia esta postagem como um bom recurso sobre essa implementação / uso. Criação dinâmica de chaves em array associativo JavaScript

Obrigado!

Vaibhav
fonte
5

Use objetos JavaScript. Você pode acessar suas propriedades como chaves em um dicionário. Esta é a base do JSON. A sintaxe é semelhante aos dicionários Python. Veja: JSON.org

Adão
fonte
4

Uma pergunta antiga, mas recentemente precisei fazer uma porta AS3> JS e, por uma questão de velocidade, escrevi um objeto Dicionário simples no estilo AS3 para JS:

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

Se você não sabia, o dicionário AS3 permite que você use qualquer objeto como chave, ao invés de apenas strings. Eles são muito úteis assim que você encontrar um uso para eles.

Não é tão rápido quanto um objeto nativo seria, mas não encontrei nenhum problema significativo com ele a esse respeito.

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
MickMalone1983
fonte
1
Biblioteca agradável e útil! Eu adicionei uma função get, que eu pensei que estava faltando, e resolvi alguns problemas menores de sintaxe (ponto-e-vírgula faltando etc.). Aqui está o violino modificado: Dicionário em JSFiddle
Matt,
Bom trabalho, companheiro, não sei por que isso não estava lá!
MickMalone1983
2

O Firefox 13+ fornece uma implementação experimental do mapobjeto semelhante ao dictobjeto em python. Especificações aqui .

Só está disponível no firefox, mas parece melhor do que usar atributos de a new Object(). Citação da documentação:

  • Um objeto tem um protótipo, portanto, há chaves padrão no mapa. No entanto, isso pode ser contornado usando map = Object.create(null).
  • As chaves de um Objectsão Strings, onde podem ter qualquer valor para a Map.
  • Você pode obter o tamanho de um Mapfacilmente enquanto precisa controlar manualmente o tamanho de um Object.
mquandalle
fonte