Criando Dinamicamente Chaves na Matriz Associativa JavaScript


199

Como posso criar dinamicamente chaves em matrizes associativas javascript?

Toda a documentação que encontrei até agora é para atualizar chaves que já foram criadas:

 arr['key'] = val;

Eu tenho uma string como esta " name = oscar "

E eu quero terminar com algo assim:

{ name: 'whatever' }

Ou seja, divido a string e obtenho o primeiro elemento, e quero colocar isso em um dicionário.

Código

var text = ' name = oscar '
var dict = new Array();
var keyValuePair = text.split(' = ');
dict[ keyValuePair[0] ] = 'whatever';
alert( dict ); // prints nothing.

24
Ir link para resposta de Eugene por conveniência
user56reinstatemonica8

Respostas:


143

Use o primeiro exemplo. Se a chave não existir, ela será adicionada.

var a = new Array();
a['name'] = 'oscar';
alert(a['name']);

Irá aparecer uma caixa de mensagem contendo 'oscar'.

Experimentar:

var text = 'name = oscar'
var dict = new Array()
var keyValuePair = text.replace(/ /g,'').split('=');
dict[ keyValuePair[0] ] = keyValuePair[1];
alert( dict[keyValuePair[0]] );

Eu executei isso como uma amostra no Firefox apenas para ter certeza. Você se certificou de colocar 'nome' entre aspas?
tvanfosson 9/12/08

1
Não, não, porque estou criando a chave "dinamicamente" e não estaticamente. Deixa-me dar uma
olhada dupla de

2
Por favor, consulte a explicação mais completa de Danny. Você não poderá se referir aos valores da matriz em um loop for com um índice (como myarray [i]). Espero que não seja muito confuso.
MK_Dev 9/12/08

4
Ainda melhor é usar um objeto (notação de colchete {}) para evitar a sobrecarga de ter .length, .slice (), etc., incluídos no protótipo de matriz
Bjornl

488

De alguma forma, todos os exemplos, embora funcionem bem, são muito complicados:

  • Eles usam new Array() , que é um exagero (e uma sobrecarga) para uma matriz associativa simples (dicionário AKA).
  • Os melhores usam new Object(). Funciona bem, mas por que toda essa digitação extra?

Esta pergunta está marcada como "iniciante", então vamos simplificar.

A maneira super simples de usar um dicionário em JavaScript ou "Por que o JavaScript não possui um objeto de dicionário especial?":

// create an empty associative array (in JavaScript it is called ... Object)
var dict = {};   // huh? {} is a shortcut for "new Object()"

// add a key named fred with value 42
dict.fred = 42;  // we can do that because "fred" is a constant
                 // and conforms to id rules

// add a key named 2bob2 with value "twins!"
dict["2bob2"] = "twins!";  // we use the subscript notation because
                           // the key is arbitrary (not id)

// add an arbitrary dynamic key with a dynamic value
var key = ..., // insanely complex calculations for the key
    val = ...; // insanely complex calculations for the value
dict[key] = val;

// read value of "fred"
val = dict.fred;

// read value of 2bob2
val = dict["2bob2"];

// read value of our cool secret key
val = dict[key];

Agora vamos alterar os valores:

// change the value of fred
dict.fred = "astra";
// the assignment creates and/or replaces key-value pairs

// change value of 2bob2
dict["2bob2"] = [1, 2, 3];  // any legal value can be used

// change value of our secret key
dict[key] = undefined;
// contrary to popular beliefs assigning "undefined" does not remove the key

// go over all keys and values in our dictionary
for (key in dict) {
  // for-in loop goes over all properties including inherited properties
  // let's use only our own properties
  if (dict.hasOwnProperty(key)) {
    console.log("key = " + key + ", value = " + dict[key]);
  }
}

A exclusão de valores também é fácil:

// let's delete fred
delete dict.fred;
// fred is removed, the rest is still intact

// let's delete 2bob2
delete dict["2bob2"];

// let's delete our secret key
delete dict[key];

// now dict is empty

// let's replace it, recreating all original data
dict = {
  fred:    42,
  "2bob2": "twins!"
  // we can't add the original secret key because it was dynamic,
  // we can only add static keys
  // ...
  // oh well
  temp1:   val
};
// let's rename temp1 into our secret key:
if (key != "temp1") {
  dict[key] = dict.temp1; // copy the value
  delete dict.temp1;      // kill the old key
} else {
  // do nothing, we are good ;-)
}

2
Olá, eu sei que estou respondendo à resposta antiga, mas ela está no topo do Google, então vou perguntar assim mesmo. Estou meio confuso com o que "não podemos adicionar a chave secreta original porque era dinâmica, podemos apenas adicionar chaves estáticas" no seu exemplo.
22411 Karel Bílek

1
Significa exatamente o que diz: não sabemos seu valor, portanto, não podemos representá-lo como uma constante, o que é necessário ao especificar uma chave em um literal de objeto.
Eugene Lazutkin

3
No entanto, "não podemos adicionar a chave secreta original porque ela era dinâmica" não está correta por si só, mesmo que você não possa usar uma variável como chave diretamente em {} ou como chave com notação de ponto. Ainda podemos adicionar uma chave dinâmica através de "dict [key] = val", como você mostra no início do exemplo. A limitação está no uso da notação {}, em vez da própria chave.
Zut

8
Isto parece de Sheldon Cooper resposta :)
jpatiaga

4
aperfeiçoar resposta completa, deve ser o padrão
Dennis Golomazov

29

Javascript não possui matrizes associativas , possui objetos .

As seguintes linhas de código fazem exatamente a mesma coisa - defina o campo 'name' em um objeto como 'orion'.

var f = new Object(); f.name = 'orion';
var f = new Object(); f['name'] = 'orion';
var f = new Array(); f.name = 'orion';
var f = new Array(); f['name'] = 'orion';
var f = new XMLHttpRequest(); f['name'] = 'orion';

Parece que você tem uma matriz associativa porque uma Arraytambém é uma Object- no entanto, você não está realmente adicionando coisas à matriz, mas sim definindo campos no objeto.

Agora que isso está esclarecido, aqui está uma solução funcional para o seu exemplo

var text = '{ name = oscar }'
var dict = new Object();

// Remove {} and spaces
var cleaned = text.replace(/[{} ]/g, '');

// split into key and value
var kvp = cleaned.split('=');

// put in the object
dict[ kvp[0] ] = kvp[1];
alert( dict.name ); // prints oscar.

Assumindo a cadeia de texto, na verdade, tem as chaves, você poderia mais ou menos tratá-lo como JSON .. substituir o sinal = com um: e você tem um objeto para eval ..
neonski

1
Opa, a sequência não está delimitada corretamente. Nada regex não pode corrigir.
neonski 9/12/08

9

Em resposta ao MK_Dev, é possível iterar, mas não consecutivamente. (Para isso, obviamente, é necessário um array)

Pesquisa rápida do Google exibe tabelas de hash em javascript

Exemplo de código para fazer loop sobre valores em um hash (do link mencionado acima):

var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;

// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

5

Código original (eu adicionei os números das linhas para que eles possam se referir a eles):

1  var text = ' name = oscar '
2  var dict = new Array();
3  var keyValuePair = text.split(' = ');
4  dict[ keyValuePair[0] ] = 'whatever';
5  alert( dict ); // prints nothing.

Quase lá...

  • linha 1: você deve fazer um trimtexto assim name = oscar.
  • linha 3: ok, desde que você SEMPRE tenha espaços à sua volta. pode ser melhor não estar trimna linha 1, use =e apare cada keyValuePair
  • adicione uma linha após 3 e antes de 4:

    key = keyValuePair[0];`
  • linha 4: Agora passa a:

    dict[key] = keyValuePair[1];
  • linha 5: mude para:

    alert( dict['name'] );  // it will print out 'oscar'

O que estou tentando dizer é que dict[keyValuePair[0]]isso não funciona, você precisa definir uma string keyValuePair[0]e usá-la como chave associativa. Essa é a única maneira que eu tenho o meu para trabalhar. Depois de configurá-lo, você pode consultá-lo com índice numérico ou digitar aspas.

Espero que ajude.


4

Todos os navegadores modernos suportam um mapa , que é uma restrição de dados de chave / valor. Existem algumas razões que tornam o uso de um mapa melhor que o Object:

  • Um objeto tem um protótipo, portanto, existem chaves padrão no mapa.
  • As chaves de um Objeto são Strings, onde podem ter qualquer valor para um Mapa.
  • Você pode obter facilmente o tamanho de um mapa enquanto precisa controlar o tamanho de um objeto.

Exemplo:

var myMap = new Map();

var keyObj = {},
    keyFunc = function () {},
    keyString = "a string";

myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

myMap.size; // 3

myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

Se você deseja que as chaves não referenciadas de outros objetos sejam coletadas como lixo, considere usar um WeakMap em vez de um Mapa.



1
var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

isso está ok, mas itera por todas as propriedades do objeto array. se você deseja iterar apenas pelas propriedades myArray.one, myArray.two ... você tenta assim

myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
myArray.push("one");
myArray.push("two");
myArray.push("three");
for(i=0;i<maArray.length;i++{
    console.log(myArray[myArray[i]])
}

agora você pode acessar o myArray ["one"] e iterar apenas por essas propriedades.


Você contou a contagem de erros de digitação no seu exemplo? :-) maArray, esquecido fechado ')' ...
Brian Haak

Obrigado pelo exemplo. Poderíamos nos unir Arraye Objecttrabalhar apenas com Objectárvores! Visão maravilhosa! É muito útil fazer Object.getOwnPropertyNames(obj/array)!
precisa

1
var obj = {};

                for (i = 0; i < data.length; i++) {
                    if(i%2==0) {
                        var left = data[i].substring(data[i].indexOf('.') + 1);
                        var right = data[i + 1].substring(data[i + 1].indexOf('.') + 1);

                        obj[left] = right;
                        count++;
                    }
                }
                console.log("obj");
                console.log(obj);
                // show the values stored
                for (var i in obj) {
                    console.log('key is: ' + i + ', value is: ' + obj[i]);
                }

            }
        };

}

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.