在 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,忘记关闭 ')'... 感谢您的示例。我们可以联合Array
和Object
并且只使用Object
树!奇妙的洞察力!制作Object.getOwnPropertyNames(obj/array)
非常有用!
此语法无效:for(i=0;i<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 关联数组中动态创建键的主要内容,如果未能解决你的问题,请参考以下文章