使用jQuery获取JavaScript关联数组的长度

8

我正在使用 JavaScript 的关联数组,例如:

var testarray = [];
testarray['one'] = '1';
testarray['two'] = '2';
testarray['three'] = '3';

我同时也在使用jquery。我该如何使用jquery或其他方法检查这个关联数组的长度?基本上,我想要检查这个数组是否为空。
谢谢。

1
重复;好答案 @ https://dev59.com/QXVD5IYBdhLWcg3wWaVh - Michael Paulukonis
1
JavaScript没有“关联数组”,它有“数组”和“对象”。如果您想使用命名属性,请使用普通对象({})而不是数组。 - Quentin
@David:语义上讲,但我会反过来说:所有 JavaScript 对象都是关联数组(不仅仅是 Array 类型,当然它也是)。它们有字符串键可以枚举,可以随意添加和删除条目(delete),等等。 (如果您不使用数字索引,则不要使用 Array。) - T.J. Crowder
2
另外,我想指出jQuery只是一个库 - 没有必要担心使用jQuery做某些事情,因为你可以使用纯粹的javascript,即使你正在进行由一些jQuery调用触发的函数回调。jQuery不是一种语言-但它非常强大。 - belugabob
1
@belugabob:+1,这种情况下jQuery确实有帮助(请参见CMS的答案),虽然这种情况并不经常发生。 - T.J. Crowder
7个回答

21

不应该使用数组来存储非数字索引,应该使用简单的对象:

function getObjectLength (o) {
  var length = 0;

  for (var i in o) {
    if (Object.prototype.hasOwnProperty.call(o, i)){
      length++;
    }
  }
  return length;
}

编辑:由于您正在使用jQuery,并且希望检查对象是否为空,1.4版本引入了$.isEmptyObject

if ($.isEmptyObject(obj)) { 
  //...
}

哦,我喜欢你从对象原型中获取“hasOwnProperty” :-) - Pointy
你不应该使用数组仅存储非数字索引(正如我在我的答案中所说),但是我并不认为在用于其“正常”目的的数组上同时存储非数字信息会有任何问题。 - T.J. Crowder
为什么不在 o 对象本身上使用 hasOwnProperty 来避免可能被替换的情况? - T.J. Crowder
@T.J. Crowder:是的,安全第一,否则getObjectLength({hasOwnProperty: 'foo'})将会使函数抛出一个TypeError... - Christian C. Salvadó
谢谢,我明白了。不过我认为我会听从对象作者的意见。如果他们有充分的理由来覆盖它,那么我应该尊重他们的决定(即使这意味着他们自己可能会出问题)。 - T.J. Crowder

13

这将给出您的关联数组的长度:

Object.keys(testarray).length

10

没有直接的“length”或“size”调用,您必须测试对象中可用的键。

请注意,所有 JavaScript 对象都是关联数组(映射),因此您的代码可能最好使用通用对象而不是数组:

var testarray = {}; // <= only change is here
testarray['one'] = '1';
testarray['two'] = '2';
testarray['three'] = '3';

你可以使用 for..in 来获取对象中的键:

var name;
for (name in testarray) {
    // name will be 'one', then 'two', then 'three' (in no guaranteed order)
}

你可以使用它来构建一个函数,检测对象是否为空。

function isEmpty(obj) {
    var name;
    for (name in obj) {
        return false;
    }
    return true;
}

正如CMS在他的回答中指出的那样,这将遍历所有的键,包括对象原型上的键。如果你只想获取对象上的键而不是其原型上的键,可以使用内置的hasOwnProperty函数:

function isEmpty(obj) {
    var name;
    for (name in obj) {
        if (obj.hasOwnProperty(name)) {
            return false;
        }
    }
    return true;
}

4
还要不要忘记使用hasOwnProperty()来避免计算原型中的属性。 - MBO
1
可能应该使用“hasOwnProperty”技巧,如果我没有沉迷于stackoverflow的话,我就不会知道这个。 - Pointy

2

我也遇到了这个问题,后来发现了解决方法(而且在我的浏览器上测试通过):

//given: ass_arr, an associative array
//result: count now holds the "length" of ass_arr 
var count = 0;
$.each(ass_arr, function(key, val) { count+=1; } );
alert(count); //number of iterable attributes in ass_arr

如果这对你有用,请让我知道!我将像这样直接将其编写到我的代码中:

var devices = STATUS.devices,
  num_devices = 0;
$.each(devices, function(id, device) { num_devices+=1; } );
//num_devices set to number of devices

0

那里实际上没有一个数组,所以我建议不要将其初始化为数组:

var testNotArray = { };
testNotArray['one'] = 'something';
// ...

现在这本质上是很危险的,但第一步可能是:

function objectSize(o) {
  var c = 0;
  for (var k in o) 
    if (o.hasOwnProperty(k)) ++c;
  return c;
}

同样,有一百万种奇怪的方式可能导致那种方法失败。


0
你可以像下面这样计算长度:
var testarray = {}; // Use a generic object to store non-numeric indexes not an array
testarray['one'] = '1';
testarray['two'] = '2';
testarray['three'] = '3';
var count = 0
for each(key in testarray)
 count = count + 1
alert(count); // count contains the number of items in the array

0
你可以循环遍历属性并计数:
var cnt = 0;
for (i in testarray) cnt++;
alert(cnt);

请注意,for (... in ...) 循环也会遍历原型添加的属性,所以你可能只想计算之后添加的属性:
var cnt = 0;
for (i in testarray) if (testarray.hasOwnProperty(i)) cnt++;
alert(cnt);

如果您只想检查是否存在任何属性,可以在第一项后退出循环:

var empty = true;
for (i in testarray) if (testarray.hasOwnProperty(i)) { empty = false; break; }
alert(empty);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接