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.
OscarRyz
fonte
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]] );
tvanfosson
fonte
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 ;-)
}
Eugene Lazutkin
fonte
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.
Orion Edwards
fonte
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]);
}
Danny
fonte
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.

Andrea
fonte
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.

Vitalii Fedorenko
fonte
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.

Sasinda Rukshan
fonte
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]);
                }

            }
        };

}

user2266928
fonte