在 JavaScript 的关联数组中使用整数作为键

Posted

技术标签:

【中文标题】在 JavaScript 的关联数组中使用整数作为键【英文标题】:Using an integer as a key in an associative array in JavaScript 【发布时间】:2011-01-01 10:55:15 【问题描述】:

当我创建一个新的 javascript 数组并使用整数作为键时,该数组中直到整数的每个元素都被创建为未定义。

例如:

var test = new Array();
test[2300] = 'Some string';
console.log(test);

将输出 2298 个未定义的和一个 'Some string'。

我应该如何让 JavaScript 使用 2300 作为字符串而不是整数,或者我应该如何防止它实例化 2299 空索引?

【问题讨论】:

【参考方案1】:

正如人们所说,使用一个对象。但是请注意,您可以拥有整数键。 JavaScript 将将整数转换为字符串。以下输出 20,不是未定义的:

var test = 
test[2300] = 20;
console.log(test["2300"]);

【讨论】:

+1 请注意,数组也是如此!见***.com/questions/1450957/… @bobince:在内部,当然。然而,逻辑上,数组有整数“键”。 请注意,使用整数作为键会改变数组的长度。您绝对应该改用 Object 。我只是想使用 facebook id 作为键,而 JSON.stringify 会使我的机器崩溃;) @LightnessRacesinOrbit 内部细节仍然会泄露出去并咬你一口。看看我今天遇到的这个简化版本:jsfiddle.net/cincodenada/pseujLex/2 缩减后它可能看起来做作,但它是更大脚本的一个有意义的部分(并且在 CoffeeScript 中不那么做作:jsfiddle.net/cincodenada/oojr7Ltn/2)。今天这个看似实现的细节让我花了很多时间寻找错误。 对非整数的一点说明:0.25.25 解析为相同的字符串 "0.25"。因此,如果您使用小数键,则可以使用 0.25.25"0.25" 而不是 ".25" 检索数字设置键 0.25 的属性。【参考方案2】:

编译其他答案:

对象

var test = ;

当使用数字作为新属性的键时,数字会变成字符串:

test[2300] = 'Some string';
console.log(test['2300']);
// Output: 'Some string'

当使用同一个数字访问属性的值时,数字又变成了一个字符串:

console.log(test[2300]);
// Output: 'Some string'

但是,当从对象中获取键时,它们不会被转换回数字:

for (var key in test) 
    console.log(typeof key);

// Output: 'string'

地图

ECMAScript 6 允许使用 Map 对象(documentation、a comparison with Object)。如果您的代码要在本地解释或 the ECMAScript 6 compatibility table 对于您的目的看起来足够绿色,请考虑使用 Map:

var test = new Map();
test.set(2300, 'Some string');
console.log(test.get(2300));
// Output: 'Some string'

不进行类型转换,无论好坏:

console.log(test.get('2300'));
// Output: undefined
test.set('2300', 'Very different string');
console.log(test.get(2300));
// Output: 'Some string'

【讨论】:

【参考方案3】:

如果用例将数据存储在集合中,则 ECMAScript 6 提供 Map 类型。

只是初始化比较重。

这是一个例子:

const map = new Map();
map.set(1, "One");
map.set(2, "Two");
map.set(3, "Three");

console.log("=== With Map ===");

for (const [key, value] of map) 
    console.log(`$key: $value ($typeof(key))`);


console.log("=== With Object ===");

const fakeMap = 
    1: "One",
    2: "Two",
    3: "Three"
;

for (const key in fakeMap) 
    console.log(`$key: $fakeMap[key] ($typeof(key))`);

结果:

=== With Map ===
1: One (number)
2: Two (number)
3: Three (number)
=== With Object ===
1: One (string)
2: Two (string)
3: Three (string)

【讨论】:

【参考方案4】:

有时我会为我的键使用前缀。例如:

var pre = 'foo',
    key = pre + 1234

obj = ;

obj[key] = val;

现在您访问它们没有任何问题。

【讨论】:

【参考方案5】:

当属性名称为整数时,获取关联数组属性的值:

从属性名称为整数的关联数组开始:

var categories = [
    "1": "Category 1",
    "2": "Category 2",
    "3": "Category 3",
    "4": "Category 4"
];

将项目推送到数组:

categories.push("2300": "Category 2300");
categories.push("2301": "Category 2301");

遍历数组并对属性值做一些事情。

for (var i = 0; i < categories.length; i++) 
    for (var categoryid in categories[i]) 
        var category = categories[i][categoryid];
        // Log progress to the console
        console.log(categoryid + ": " + category);
        //  ... do something
    

控制台输出应如下所示:

1: Category 1
2: Category 2
3: Category 3
4: Category 4
2300: Category 2300
2301: Category 2301

如您所见,您可以绕过关联数组的限制,让属性名称为整数。

注意:我的示例中的关联数组是序列化 Dictionary[] 对象时的 JSON 内容。

【讨论】:

【参考方案6】:

正如人们所说,JavaScript 会将数字字符串转换为整数,因此无法直接在关联数组上使用,但我认为对象会以类似的方式为您工作。

你可以创建你的对象:

var object = ;

并添加值作为数组的作品:

object[1] = value;
object[2] = value;

这会给你:


  '1': value,
  '2': value

之后你就可以像访问其他语言的数组一样获取密钥了:

for(key in object)

   value = object[key] ;

我已经测试并工作了。

【讨论】:

【参考方案7】:

使用对象 - 以整数作为键 - 而不是数组。

【讨论】:

【参考方案8】:

使用对象而不是数组。 JavaScript 中的数组不是关联数组。它们是具有与名称看起来像整数的任何属性相关联的魔法的对象。如果您不将它们用作传统的类似数组的结构,那么这种魔法就不是您想要的。

var test = ;
test[2300] = 'some string';
console.log(test);

【讨论】:

它们可以是关联数组,但这仅仅是因为它们也是可以设置命名属性的对象。但这只会让事情变得非常混乱,所以是的,对象更好用。 数组永远不能是关联的 Graza。如果您尝试在数组中使用键,然后对其进行迭代,您会注意到您也在迭代数组的所有默认方法和属性 -> 不是很理想。 @Swizec - 正是我说“可笑的混乱”的原因。您可以将数组用作关联数组——即名称/值对,但您永远不想迭代它们! (我只是指出了一个技术性问题,我绝对不建议这样做) 是的,但是在迭代时它们并没有任何特定的顺序(即不能保证顺序),这将是对它们进行编号的重点,所以这比仅仅混淆要糟糕得多。【参考方案9】:

尝试使用对象,而不是数组:

var test = new Object(); test[2300] = 'Some string';

【讨论】:

这绝对是要走的路。这样您就不会为了存储单个字符串而创建 2300 个条目的长数组。 @Krystian JS 数组是假数组。运行var a = []; a[Math.pow(2, 30)] = 'hello';,您不会看到浏览器/内存使用量激增超过 1 GB,但您会看到a.length 是 1073741824。VM 显然使用其他数据结构存储了一些“数组”,我只是猜测一个哈希表,至少在它们足够稀疏的情况下。【参考方案10】:

你可以只使用一个对象:

var test = 
test[2300] = 'Some string';

【讨论】:

仍然被转换成字符串。 @drew010 是的,Javascript 的对象只允许使用字符串进行索引。

以上是关于在 JavaScript 的关联数组中使用整数作为键的主要内容,如果未能解决你的问题,请参考以下文章

使用整数键创建关联数组

第四章 数组关联数组和别名使用

shell 常规数组&关联数组

5.9 作为关联数组的对象

shell关联数组

在 PHP 中按整数键对对象进行排序