Como criar dicionário e adicionar pares chave-valor dinamicamente?

324

Da postagem:

Enviando uma matriz JSON para ser recebida como um Dicionário <string, string>

Estou tentando fazer a mesma coisa que esse post. O único problema é que não sei quais são as chaves e os valores iniciais. Portanto, preciso adicionar dinamicamente os pares de chave e valor e não sei como fazer isso.

Alguém sabe como criar esse objeto e adicionar pares de valores-chave dinamicamente?

Eu tentei:

var vars = [{key:"key", value:"value"}];
vars[0].key = "newkey";
vars[0].value = "newvalue";

Mas isso não funciona.

KenEucker
fonte
2
Isso funciona muito bem. console.log (vars); mostre-me [chave do objeto: valor "newkey" : proto "newvalue" : objeto] #
Alex Pliutau #
Exceto por uma lista, não um dicionário: \ Acho que os dados são melhor representados como uma lista de "pares" também list = [["key1","value1"],["key2","value2"]]. Alguns outros idiomas têm um tipo de "par" ou "tupla". tldr para adição de ditado real:dict['key'] = "value"
Jordan Stewart

Respostas:

553
var dict = []; // create an empty array

dict.push({
    key:   "keyName",
    value: "the value"
});
// repeat this last part as needed to add more key/value pairs

Basicamente, você está criando um literal de objeto com 2 propriedades (chamado keye value) e o inserindo (usando push()) na matriz.


Edit: Então, quase 5 anos depois, esta resposta está recebendo votos negativos porque não está criando um literal de objeto JS "normal" (aka mapa, aka hash, aka dicionário).
No entanto, está criando a estrutura que o OP solicitou (e que é ilustrada na outra questão vinculada a), que é uma matriz de literais de objetos , cada um com propriedades keye value. Não me pergunte por que essa estrutura foi necessária, mas foi solicitada.

Mas, mas, se o que você deseja em um objeto JS simples - e não na estrutura solicitada pelo OP - veja a resposta do tcll , embora a notação entre colchetes seja um pouco complicada se você tiver apenas chaves simples com nomes JS válidos. Você pode fazer isso:

// object literal with properties
var dict = {
  key1: "value1",
  key2: "value2"
  // etc.
};

Ou use a notação de ponto regular para definir propriedades depois de criar um objeto:

// empty object literal with properties added afterward
var dict = {};
dict.key1 = "value1";
dict.key2 = "value2";
// etc.

Você não quer que a notação de colchetes se você tem as chaves que têm espaços entre eles, caracteres especiais, ou coisas assim. Por exemplo:

var dict = {};

// this obviously won't work
dict.some invalid key (for multiple reasons) = "value1";

// but this will
dict["some invalid key (for multiple reasons)"] = "value1";

Você também deseja notação de colchete se suas chaves forem dinâmicas:

dict[firstName + " " + lastName] = "some value";

Observe que as chaves (nomes de propriedades) são sempre cadeias e os valores que não são de cadeia serão coagidos a uma cadeia quando usados ​​como uma chave. Por exemplo, um Dateobjeto é convertido em sua representação de string:

dict[new Date] = "today's value";

console.log(dict);
// => {
//      "Sat Nov 04 2016 16:15:31 GMT-0700 (PDT)": "today's value"
//    }

Observe, no entanto, que isso não necessariamente "apenas funciona", pois muitos objetos terão uma representação de string como "[object Object]" que não cria uma chave não exclusiva. Portanto, tenha cuidado com algo como:

var objA = { a: 23 },
    objB = { b: 42 };

dict[objA] = "value for objA";
dict[objB] = "value for objB";

console.log(dict);
// => { "[object Object]": "value for objB" }

Apesar objAeobjB por serem elementos completamente diferentes e únicos, ambos têm a mesma representação básica string: "[object Object]".

O motivo Datenão se comporta dessa maneira é que o Dateprotótipo possui um toStringmétodo personalizado que substitui a representação de string padrão. E você pode fazer o mesmo:

// a simple constructor with a toString prototypal method
function Foo() {
  this.myRandomNumber = Math.random() * 1000 | 0;
}

Foo.prototype.toString = function () {
  return "Foo instance #" + this.myRandomNumber;
};

dict[new Foo] = "some value";

console.log(dict);
// => {
//      "Foo instance #712": "some value"
//    }

(Observe que, como o descrito acima, usa um método aleatório número , as colisões de nomes ainda podem ocorrer com muita facilidade. É apenas para ilustrar uma implementação de toString.)

Portanto, ao tentar usar objetos como chaves, o JS usará a própria toStringimplementação do objeto , se houver, ou usará a representação de sequência padrão.

Flambino
fonte
2
Isso é associativo?
precisa saber é o seguinte
1
@CsabaToth Não, dictnão é um dicionário associativo. É uma matriz de objetos, cada um dos quais é um dicionário com duas chaves: "chave" e "valor".
Roman Starkov
1
O que você tem lá é uma matriz que é meramente denominada 'dict'.
Jan Kyu Peblik
2
Aprecie a atualização e acompanhe informações adicionais.
Jacob
410
var dict = {};

dict['key'] = "testing";

console.log(dict);

funciona como python :)

saída do console:

Object {key: "testing"} 
Tcll
fonte
3
Esta é certamente a melhor abordagem para a construção de um dicionário e é a resposta correta!
Roman
3
Muito importante para inicializado com suportes {}em vez de parênteses
Jaider
Eu também uso objetos básicos como dicionários como este. Fico feliz em ver que é o caminho certo!
TKoL 02/02
5
'Beleza' do javascript! Objeto é actualy uma chave dicionário próprio valor par
100r
1
@Azurespot, a chave pode ser qualquer coisa lavável, afinal as chaves são ordenadas por hash, o que em python3 difere a cada execução.
Tcll 15/08/19
53

É tão simples quanto:

var blah = {}; // make a new dictionary (empty)

ou

var blah = {key: value, key2: value2}; // make a new dictionary with two pairs 

então

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2
Simon Sarris
fonte
1
@ KenEucker Eu acho que é útil ter respostas erradas em perguntas como esta. Especialmente se alguém explica por que está errado, é um bom recurso de aprendizado.
CJBrew
32

Desde que você declarou que deseja um objeto de dicionário (e não uma matriz como eu assumo que alguns entendam), acho que é isso que você procura:

var input = [{key:"key1", value:"value1"},{key:"key2", value:"value2"}];

var result = {};

for(var i = 0; i < input.length; i++)
{
    result[input[i].key] = input[i].value;
}

console.log(result); // Just for testing
ZenMaster
fonte
A outra solução usando .push em uma matriz funciona para meus usos, mas presumo que isso também funcionaria se eu tentasse.
precisa saber é o seguinte
2
A menos que eu entenda mal o que é um objeto Dictionary, sua pergunta é enganosa. Como você recuperaria um valor por chave da sua matriz?
ZenMaster 25/08
Eu estou usando JSON.stringify nesse objeto e, em seguida, capturando-o com um controlador no MVC 3. Isso é apenas para que ele seja formatado corretamente antes de o estripar e enviá-lo.
precisa saber é o seguinte
23

JavaScript Object é em si mesmo como um dicionário. Não há necessidade de reinventar a roda.

var dict = {};

// Adding key-value -pairs
dict['key'] = 'value'; // Through indexer
dict.anotherKey = 'anotherValue'; // Through assignment

// Looping through
for (var item in dict) {
  console.log('key:' + item + ' value:' + dict[item]);
  // Output
  // key:key value:value
  // key:anotherKey value:anotherValue
}

// Non existent key
console.log(dict.notExist); // undefined

// Contains key?
if (dict.hasOwnProperty('key')) {
  // Remove item
  delete dict.key;
}

// Looping through
for (var item in dict) {
  console.log('key:' + item + ' value:' + dict[item]);
  // Output
  // key:anotherKey value:anotherValue
}

Violino

Jani Hyytiäinen
fonte
11

Você pode usar mapas com Map, assim:

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
Preetham Kumar P
fonte
9

Por acaso, passei por essa pergunta procurando algo semelhante. Isso me deu informações suficientes para executar um teste e obter a resposta que eu queria. Portanto, se alguém quiser saber como adicionar ou procurar dinamicamente um par {key: 'value'} em um objeto JavaScript, esse teste deve informar tudo o que você precisa saber.

var dictionary = {initialkey: 'initialValue'};
var key = 'something';
var key2 =  'somethingElse';
var value = 'value1';
var value2 = 'value2';
var keyInitial = 'initialkey';

console.log(dictionary[keyInitial]);

dictionary[key] =value;
dictionary[key2] = value2;
console.log(dictionary);

resultado

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }
user2301449
fonte
2
Isto não é uma pergunta. Em vez disso, você deve fazer a pergunta e responder você mesmo. Isso seria muito mais fácil de entender e organizar.
SalmonKiller
1
obrigado @SalmonKiller eu não tinha certeza da terminologia adequada para escrever minha própria pergunta e esperava que ela fosse entendida, mas então eu me deparei com isso na minha pesquisa. Todas as informações estavam lá, mas se espalharam por várias respostas, então eu respondi o conceito dessa pergunta em um forma que iria respondê-la para alguém que tropeçou na esta pergunta olhando para a mesma coisa que me
user2301449
1
RI MUITO. Eu estava analisando isso e parecia uma pergunta em vez de uma resposta. Me desculpe, cara!
SalmonKiller
Obrigado por adicionar isso. Você também pode colocá-lo em um violino, como a resposta acima.
KenEucker 14/05
8
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1
SharpCoder
fonte
para alguns desempenho adicional, você deve fazer referência key1 = dictionary.key1ao invés de índicekey1 = dictionary["key1"]
Tcll
4

Você pode criar um dicionário de classe para interagir facilmente com a lista Dicionário:

class Dictionary {
  constructor() {
    this.items = {};
  }
  has(key) {
    return key in this.items;
  }
  set(key,value) {
    this.items[key] = value;
  }
  delete(key) {
    if( this.has(key) ){
      delete this.items[key]
      return true;
    }
    return false;
  }
}

var d = new Dictionary();
d.set(1, "value1")
d.set(2, "value2")
d.set(3, "value3")
console.log(d.has(2));
d.delete(2);
console.log(d.has(2));

agonza1
fonte
3

e o liner único para criar um par de valores-chave?

let result = { ["foo"]: "some value" };

e algumas funções do iterador gostam reducede converter dinamicamente uma matriz em um dicionário

var options = [
  { key: "foo", value: 1 },
  { key: "bar", value: {id: 2, name: "two"} },
  { key: "baz", value: {["active"]: true} },
];

var result = options.reduce((accumulator, current) => {
  accumulator[current.key] = current.value;
  return accumulator;
}, {});

console.log(result);

Dan Dohotaru
fonte
3

No javascript moderno (ES6 / ES2015), deve-se usar a estrutura de dados do mapa para o dicionário. A estrutura de dados do mapa no ES6 permite usar valores arbitrários como chaves.

const map = new Map();
map.set("true", 1);
map.set("false", 0);

Enquanto você ainda usa o ES5, a maneira correta de criar dicionário é criar objeto sem um protótipo da seguinte maneira.

var map = Object.create(null);
map["true"]= 1;
map["false"]= 0;

Há muitas vantagens em criar um dicionário sem um objeto de protótipo. Os blogs abaixo valem a pena ler sobre esse tópico.

padrão de ditado

objetos-como-mapas

Jyoti Prasad Pal
fonte
2

Ajudaria muito saber qual é o seu resultado final desejado, mas acho que é isso que você deseja:

var vars = [{key:"key", value:"value"}];

vars.push({key: "newkey", value: "newvalue"})
gddc
fonte
2

Corri para este problema .. mas dentro de um loop for. A solução superior não funcionou (ao usar variáveis ​​(e não cadeias) para os parâmetros da função push), e as outras não foram responsáveis ​​por valores-chave baseados em variáveis. Fiquei surpreso que esta abordagem (que é comum em php) funcionou ..

  // example dict/json                  
  var iterateDict = {'record_identifier': {'content':'Some content','title':'Title of my Record'},
    'record_identifier_2': {'content':'Some  different content','title':'Title of my another Record'} };

  var array = [];

  // key to reduce the 'record' to
  var reduceKey = 'title';

  for(key in iterateDict)
   // ultra-safe variable checking...
   if(iterateDict[key] !== undefined && iterateDict[key][reduceKey] !== undefined)
    // build element to new array key
     array[key]=iterateDict[key][reduceKey];
redcap3000
fonte
1

Uma melhoria var dict = {}é usarvar dict = Object.create(null) .

Isso criará um objeto vazio que não possui Object.prototypecomo protótipo.

var dict1 = {};
if (dict1["toString"]){
    console.log("Hey, I didn't put that there!")
}
var dict2 = Object.create(null);
if (dict2["toString"]){
    console.log("This line won't run :)")
}
De madeira
fonte
1

Inicialize a primeira matriz globalmente

var dict = []

Adicionar objeto ao dicionário

dict.push(
     { key: "One",value: false},
     { key: "Two",value: false},
     { key: "Three",value: false});

Output : 
   [0: {key: "One", value: false}
    1: {key: "Two", value: false}
    2: {key: "Three", value: false}]

Atualizar objeto do dicionário

Object.keys(dict).map((index) => {        
  if (index == 1){
    dict[index].value = true
  }
});

Output : 
   [0: {key: "One", value: false},
    1: {key: "Two", value: true},
    2: {key: "Three", value: false}]

Excluir objeto do dicionário

Object.keys(dict).map((index) => {              
      if (index == 2){
        dict.splice(index)
      }
    });

Output : 
    [0: {key: "One", value: false},
     1: {key: "Two", value: true}]
Pratik Panchal
fonte