【问题标题】:How to create dictionary and add key–value pairs dynamically?如何动态创建字典和添加键值对?
【发布时间】:2011-11-04 00:04:49
【问题描述】:

来自帖子:

Sending a JSON array to be received as a Dictionary<string,string>

我正在尝试做与该帖子相同的事情。唯一的问题是我不知道预先设置的键和值是什么。所以我需要能够动态添加键值对,但我不知道该怎么做。

有谁知道如何创建该对象并动态添加键值对?

我试过了:

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

但这不起作用。

【问题讨论】:

  • 效果很好。控制台.log(vars);告诉我[对象键:“newkey”值:“newvalue”proto:对象]
  • 除了它是一个列表,而不是字典:\ 我认为数据最好也表示为“对”列表,例如list = [["key1","value1"],["key2","value2"]]。其他一些语言有“对”或“元组”类型。 tldr 用于实际添加的 dict:dict['key'] = "value"

标签: javascript dictionary key-value


【解决方案1】:
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

基本上,您正在创建一个具有 2 个属性(称为 keyvalue)的对象字面量,并将其插入(使用 push())到数组中。


编辑:所以差不多 5 年后,这个答案越来越被否决,因为它没有创建一个“正常”的 JS 对象文字(又名映射、又名哈希、又名字典)。
然而,它正在创建 OP 要求的结构(并在链接到的另一个问题中说明),这是 一个对象文字数组,每个都有keyvalue 属性。不要问我为什么需要这种结构,但它就是被要求的结构。

但是,但是,如果你想要一个普通的 JS 对象 - 而 不是 OP 要求的结构 - 请参阅tcll's answer,尽管如果你只是简单的括号符号有点麻烦是有效的 JS 名称的键。你可以这样做:

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

或者在创建对象后使用常规的点符号来设置属性:

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

如果您的键中有空格、特殊字符或类似的东西,您确实需要括号表示法。例如:

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

如果您的键是动态的,您还需要括号表示法:

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

请注意,键(属性名)始终是字符串,非字符串值在用作键时会被强制转换为字符串。例如。 Date 对象被转换为它的字符串表示:

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

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

但是请注意,这不一定“正常工作”,因为许多对象将具有像 "[object Object]" 这样的字符串表示形式,它不会构成非唯一键。所以要警惕这样的事情:

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

尽管objAobjB 是完全不同且唯一的元素,但它们都具有相同的基本字符串表示:"[object Object]"

Date 的行为不是这样的原因是Date 原型有一个自定义的toString 方法,它覆盖了默认的字符串表示。你也可以这样做:

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

(请注意,由于上面使用了一个随机数字,名称冲突仍然很容易发生。这只是为了说明toString的实现。)

所以当尝试使用对象作为键时,JS 将使用对象自己的toString 实现,如果有的话,或者使用默认的字符串表示。

【讨论】:

  • @CsabaToth 不,dict 不是关联字典。它是一个对象数组,每个对象有点像字典,有两个键:“key”和“value”。
  • 你所拥有的只是一个名为“dict”的数组。
  • 感谢更新并跟进更多信息。
【解决方案2】:
var dict = {};

dict['key'] = "testing";

console.log(dict);

就像 python 一样工作 :)

控制台输出:

Object {key: "testing"} 

【讨论】:

  • 这无疑是构建字典的最佳方法,而且是正确答案!
  • 用括号{}而不是圆括号初始化很重要
  • 我也像这样使用基本对象作为字典。很高兴看到这是正确的方法!
  • javascript之美!对象实际上是一个键值对字典本身
  • @Azurespot 密钥可以是任何可散列的,毕竟密钥是按散列排序的,在 python3 中每次运行都不同。
【解决方案3】:

就这么简单:

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

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

然后

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2

【讨论】:

  • @KenEucker 我认为在这样的问题中有错误的答案很有用。特别是如果有人解释了他们为什么错了,这是一个很好的学习资源。
【解决方案4】:

既然你已经说过你想要一个字典对象(并且不是一个数组,我认为有些人已经理解了),我认为这就是你所追求的:

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

【讨论】:

  • 另一种使用 .push 进入数组的解决方案适用于我的用途,但我认为如果我尝试它也可以。
  • 除非我误解了 Dictionary 对象是什么,否则您的问题会产生误导。您将如何从数组中按键检索值?
  • 我在这个对象上使用 JSON.stringify,然后用 MVC 3 中的控制器捕获它。这只是为了在对其进行字符串化并发送之前正确格式化。
【解决方案5】:

JavaScript 的Object 本身就像一本字典。无需重新发明轮子。

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
}

Fiddle

【讨论】:

    【解决方案6】:

    您可以将地图与Map 一起使用,如下所示:

    var sayings = new Map();
    sayings.set('dog', 'woof');
    sayings.set('cat', 'meow');
    

    【讨论】:

      【解决方案7】:

      我碰巧遇到了这个问题,正在寻找类似的东西。它给了我足够的信息来运行测试以获得我想要的答案。因此,如果其他人想知道如何在 JavaScript 对象中动态添加或查找 {key: 'value'} 对,这个测试应该告诉你所有你可能需要知道的。

      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);
      

      输出

      initialValue
      { initialkey: 'initialValue',
        something: 'value1',
        somethingElse: 'value2' }
      

      【讨论】:

      • 这不是问题。相反,您应该做的是提出问题,然后自己回答。这样会更容易理解和组织。
      • 谢谢@SalmonKiller 我不确定用合适的术语来写我自己的问题并期望它被理解,但后来我在搜索中遇到了这个问题,所有信息都在那里,但分布在几个答案之间,所以我以某种方式回答了这个问题的概念,这将为偶然发现这个问题并寻找与我相同的东西的其他人提供答案
      • 哈哈。我正在审查这个,它看起来像一个问题而不是一个答案。对不起,伙计!
      • 感谢您添加此内容。您也可以像上面的答案一样将它放入小提琴中。
      【解决方案8】:
      var dictionary = {};//create new object
      dictionary["key1"] = value1;//set key1
      var key1 = dictionary["key1"];//get key1
      

      【讨论】:

      • 对于一些额外的性能,你应该引用key1 = dictionary.key1而不是索引key1 = dictionary["key1"]
      【解决方案9】:

      使用 ES6,您可以这样做:

      let cake = '?';
      
      let pan = {
        [cake]: '?',
      };
      
      // Output -> { '?': '?' }
      

      老路(原版 js)

      let cake = '?';
      let pan = {};
      pan[cake] = '?';
      
      // Output -> { '?': '?' }
      

      【讨论】:

      • 我喜欢这个解决方案,因为它是为现代而更新的并且非常优雅。感谢您的贡献。这对于我当时需要的东西来说是一个有效的解决方案。
      【解决方案10】:

      您可以创建一个类 Dictionary 以便您可以轻松地与 Dictionary 列表进行交互:

      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));

      【讨论】:

        【解决方案11】:

        在现代 javascript (ES6/ES2015) 中,应该使用 Map 数据结构作为字典。 ES6 中的 Map 数据结构允许您使用任意值作为键。

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

        在你还在使用 ES5 的情况下,创建字典的正确方法是通过以下方式创建没有原型的对象。

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

        在没有原型对象的情况下创建字典有很多优点。下面的博客值得一读关于这个主题。

        dict-pattern

        objects-as-maps

        【讨论】:

          【解决方案12】:

          用于创建键值对的单行如何?

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

          还有一些迭代器函数,如reduce,用于将数组动态转换为字典

          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);

          【讨论】:

            【解决方案13】:

            首先全局初始化数组

            var dict = []
            

            将对象添加到字典中

            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}]
            

            从字典中更新对象

            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}]
            

            从字典中删除对象

            Object.keys(dict).map((index) => {              
                  if (index == 2){
                    dict.splice(index)
                  }
                });
            
            Output : 
                [0: {key: "One", value: false},
                 1: {key: "Two", value: true}]
            

            【讨论】:

              【解决方案14】:

              我遇到了这个问题.. 但在 for 循环中。顶级解决方案不起作用(当使用变量(而不是字符串)作为推送函数的参数时),其他解决方案没有考虑基于变量的键值。我很惊讶这种方法(这在 php 中很常见)有效..

                // 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];
              

              【讨论】:

                【解决方案15】:

                var dict = {} 的改进是使用var dict = Object.create(null)

                这将创建一个Object.prototype作为原型的空对象。

                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 :)")
                }
                

                【讨论】:

                • 好点,否则你会得到一本装满的字典:__defineGetter__: function __defineGetter__() __defineSetter__: function __defineSetter__() __lookupGetter__: function __lookupGetter__() __lookupSetter__: function __lookupSetter__() __proto__: ​constructor: function Object() hasOwnProperty: function hasOwnProperty() hasProperty: function value(prop) isPrototypeOf: function isPrototypeOf() propertyIsEnumerable: function propertyIsEnumerable() toLocaleString: function toLocaleString() toString: function toString() ​valueOf: function valueOf()
                • 救命稻草!作为一个新手,当dict["constructor"].item 不断让我的应用崩溃时,我有点困惑。
                【解决方案16】:

                如果有人需要动态创建字典对象,可以使用下面的代码 sn-p

                   let vars = [{key:"key", value:"value"},{key:"key2", value:"value2"}];
                     let dict={}
                     vars.map(varItem=>{
                              dict[varItem.key]=varItem.value
                            })
                
                    console.log(dict)

                【讨论】:

                  【解决方案17】:

                  你可以像这样初始化字典

                  var vars = {
                  "key1": "Search",
                  "key2": "View"
                  };
                  

                  并像访问它

                  console.log(vars["key1"]);
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2023-03-08
                    • 2018-08-20
                    • 1970-01-01
                    • 2019-03-29
                    • 2015-08-24
                    • 1970-01-01
                    • 2015-08-24
                    • 2019-11-21
                    相关资源
                    最近更新 更多