在 JavaScript 关联数组中动态创建键

Posted

技术标签:

【中文标题】在 JavaScript 关联数组中动态创建键【英文标题】:Dynamically creating keys in a JavaScript associative array 【发布时间】:2010-09-25 23:23:52 【问题描述】:

到目前为止,我发现的所有文档都是更新已创建的密钥:

 arr['key'] = val;

我有一个这样的字符串:" name = oscar "

我想以这样的方式结束:

 name: 'whatever' 

即拆分字符串,获取第一个元素,然后将其放入字典中。

代码

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

【问题讨论】:

为方便起见,将链接跳转到Eugene's answer 【参考方案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]);

这没问题,但它会遍历数组对象的每个属性。

如果您只想遍历属性 myArray.one、myArray.two...,您可以这样尝试:

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

现在您可以通过 myArray["one"] 访问两者并仅通过这些属性进行迭代。

【讨论】:

您是否计算过示例中的错误输入次数? :-) maArray,忘记关闭 ')'... 感谢您的示例。我们可以联合ArrayObject 并且只使用Object 树!奇妙的洞察力!制作Object.getOwnPropertyNames(obj/array)非常有用! 此语法无效:for(i=0;i&lt;maArray.length;i++【参考方案2】:
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]);




;

【讨论】:

这是不平衡的。剩下的在哪里(有多余的三个s)?【参考方案3】:

我认为如果你像这样创建它会更好:

var arr = [];

arr = 
   key1: 'value1',
   key2:'value2'
;

有关更多信息,请查看以下内容:

javascript Data Structures - Associative Array

【讨论】:

【参考方案4】:

所有现代浏览器都支持Map,这是一种键/值数据结构。使用 Map 比使用 Object 更好的原因有两个:

一个对象有一个原型,所以映射中有默认键。 Object 的键是字符串,它们可以是 Map 的任何值。 您可以轻松获取地图的大小,同时您必须跟踪对象的大小。

例子:

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"

如果您希望对未从其他对象引用的键进行垃圾回收,请考虑使用 WeakMap 而不是 Map。

【讨论】:

【参考方案5】:

原始代码(我添加了行号,所以可以参考它们):

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.

差不多了……

第 1 行:您应该在文本上添加 trim,所以它是 name = oscar

第 3 行:只要您始终在等号周围有空格,就可以了。 最好不要在第 1 行中使用 trim。使用 = 并修剪每个 keyValuePair

在 3 之后和 4 之前添加一行:

  key = keyValuePair[0];`

第 4 行:现在变为:

  dict[key] = keyValuePair[1];

第 5 行:更改为:

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

我想说dict[keyValuePair[0]] 不起作用。您需要将字符串设置为keyValuePair[0] 并将其用作关联键。这是我让我的工作的唯一方法。设置完成后,您可以使用数字索引或键入引号来引用它。

【讨论】:

【参考方案6】:

不知何故,所有示例虽然运行良好,但都过于复杂:

他们使用new Array(),这对于简单的关联数组(AKA 字典)来说是一种过度杀伤(和开销)。 更好的使用new Object()。它运行良好,但为什么要额外输入这些内容?

这个问题被标记为“初学者”,所以让我们让它变得简单。

在 JavaScript 中使用字典的超简单方法或“为什么 JavaScript 没有特殊的字典对象?”:

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

现在让我们更改值:

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

// Change the 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) 
  // A 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]);
  

删除值也很容易:

// Let's delete fred
delete dict.fred;
// fred is removed, but 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, but
  // 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 ;-)

【讨论】:

你好,我知道我正在回复旧答案,但它在谷歌上排名很高,所以我还是会问。我对您的示例中的“我们无法添加原始密钥,因为它是动态的,我们只能添加静态密钥”的含义感到困惑。 这正是它所说的:我们不知道它的值,所以我们不能将它表示为一个常量,这是在对象字面量中指定键时所必需的。 但是,“我们无法添加原始密钥,因为它是动态的”本身是不正确的,即使您不能在 中直接使用变量作为密钥,也不能将其用作密钥用点符号。我们仍然可以通过“dict[key] = val”添加一个动态键,正如您在示例前面所展示的那样。限制在于使用 表示法,而不是密钥本身。 这看起来像 Sheldon Cooper 的回答 :) 挖吧!感谢您的帮助。【参考方案7】:

JavaScript 没有关联数组。它有对象

以下代码行都做同样的事情 - 将对象上的“名称”字段设置为“猎户座”。

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

看起来您有一个关联数组,因为 Array 也是 Object - 但是您实际上根本没有将东西添加到数组中;您正在对象上设置字段。

现在已经澄清了,这是您示例的有效解决方案:

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.

【讨论】:

假设文本字符串确实有花括号,您可以或多或少将其视为 JSON.. 将 = 符号替换为 : 并且您有一个要评估的对象..跨度> 糟糕,字符串没有正确分隔。没有任何正则表达式无法解决。【参考方案8】:

响应 MK_Dev,可以迭代,但不能连续(为此,显然需要一个数组)。

在 Google 上快速搜索会出现 hash tables in JavaScript。

在散列中循环值的示例代码(来自上述链接):

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

【讨论】:

【参考方案9】:

使用第一个示例。如果密钥不存在,则会添加它。

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

会弹出一个包含'oscar'的消息框。

试试:

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

【讨论】:

为了确定,我在 Firefox 中将其作为示例运行。你确定把“名字”放在引号里吗? 嗯,不,因为,我正在“动态”而不是静态地创建密钥。让我再检查一遍:) 请参考 Danny 更完整的解释。您将无法使用索引(例如 myarray[i])在 for 循环中引用数组值。希望这不会太令人困惑。 更好的是使用对象(方括号 表示法)来避免 .length、.slice() 等包含在 Array 原型中的开销

以上是关于在 JavaScript 关联数组中动态创建键的主要内容,如果未能解决你的问题,请参考以下文章

从 JSON 使用 Javascript 创建动态关联数组

动态创建关联数组

使用整数键创建关联数组

如何在 JavaScript 文字符号中创建关联数组

Javascript :: 如何将关联数组的键获取到数组变量?

JavaScript 关联数组的键必须是字符串,还是可以是任何对象?