2010-03-24 116 views
65

我有此代码创建的数组:如何在Javascript中获得数组键?

var widthRange = new Array(); 
widthRange[46] = { min:0, max:52 }; 
widthRange[66] = { min:52, max:70 }; 
widthRange[90] = { min:70, max:94 }; 

我想要得到的每个值46,66的,90在一个循环中。我试过for (var key in widthRange),但是这给了我一大堆额外的属性(我认为它们是对象上的函数)。由于值不是顺序的,因此我无法使用常规循环。

+8

它看起来像你有数据,而它碰巧有数字键,实际上不是数组数据。我会在这里使用一个普通的对象。 – Quentin 2010-03-24 16:31:25

回答

87

你需要调用hasOwnProperty功能检查属性是否实际上定义在对象本身上(而不是其原型),如下所示:

for (var key in widthRange) { 
    if (key === 'length' || !widthRange.hasOwnProperty(key)) continue; 
    var value = widthRange[key]; 
} 

请注意,您需要单独检查length
但是,你不应该在这里使用数组;你应该使用一个常规的对象。所有Javascript对象都作为关联数组。

例如:

var widthRange = { }; //Or new Object() 
widthRange[46] = { sel:46, min:0, max:52 }; 
widthRange[66] = { sel:66, min:52, max:70 }; 
widthRange[90] = { sel:90, min:70, max:94 }; 
+2

真的吗?哇,我每天都在这里学习东西,而且经常从你那里学到东西SLaks :-)我很惊讶Array对这种显式设置的索引进行跟踪。也许我不该。 – Pointy 2010-03-24 16:34:04

+0

@SLaks:谢谢,将它改为对象似乎是最好的解决方案。还有一个问题:有没有办法以相反的顺序进行迭代? – DisgruntledGoat 2010-03-24 17:19:47

+0

否;你需要自己做。 – SLaks 2010-03-24 17:49:05

3
for (var i = 0; i < widthRange.length; ++i) { 
    if (widthRange[i] != null) { 
    // do something 
    } 
} 

你不能真正得到你设置的键,因为这不是一个数组的工作方式。一旦你设置了元素46,你也可以设置0到45(尽管它们是空的)。

你总是可以有阵列:

var widthRange = [], widths = [], newVal = function(n) { 
    widths.push(n); 
    return n; 
}; 
widthRange[newVal(26)] = { whatever: "hello there" }; 

for (var i = 0; i < widths.length; ++i) { 
    doSomething(widthRange[widths[i]]); 
} 

编辑以及它可能是我所有的湿这里...

+0

数组只追踪长度,但它们不经过并创建多个对象。基本上,当找到一个新索引时,它会检查新索引是否大于长度......如果是新索引变为新长度。因为有可能只获得您用for-in循环定义的索引 – Bob 2010-03-24 16:40:59

1

你原来的例子只是正常工作对我来说:

<html> 
<head> 
</head> 
<body> 
<script> 
var widthRange = new Array(); 
widthRange[46] = { sel:46, min:0, max:52 }; 
widthRange[66] = { sel:66, min:52, max:70 }; 
widthRange[90] = { sel:90, min:70, max:94 }; 

var i = 1; 
for (var key in widthRange) 
{ 
    document.write("Key #" + i + " = " + key + "; &nbsp;&nbsp;&nbsp; min/max = " + widthRange[key].min + "/" + widthRange[key].max + "<br />"); 
    i++; 
} 
</script> 
</html> 

结果在浏览器(Firefox 3.6.2在Windows XP):

Key #1 = 46;  min/max = 0/52 
Key #2 = 66;  min/max = 52/70 
Key #3 = 90;  min/max = 70/94 
+2

我敢打赌,他正在导入原型或类似的东西。一般来说,那些“in”循环是有风险的。 – Pointy 2010-03-24 16:32:22

+0

嗯,我使用jQuery,但也使用mootools的Joomla,东西是添加这些属性。 – DisgruntledGoat 2010-03-24 17:09:45

0

似乎工作。

var widthRange = new Array(); 
widthRange[46] = { sel:46, min:0, max:52 }; 
widthRange[66] = { sel:66, min:52, max:70 }; 
widthRange[90] = { sel:90, min:70, max:94 }; 

for (var key in widthRange) 
{ 
    document.write(widthRange[key].sel + "<br />"); 
    document.write(widthRange[key].min + "<br />"); 
    document.write(widthRange[key].max + "<br />"); 
} 
1

我认为你应该使用一个对象({}),而不是一个数组([])这一点。

一组数据与每个键相关联。它尖叫着使用一个对象。不要:

var obj = {}; 
obj[46] = { sel:46, min:0, max:52 }; 
obj[666] = { whatever:true }; 

// This is what for..in is for 
for (var prop in obj) { 
    console.log(obj[prop]); 
} 

也许一些实用的东西像这样可以帮助:

window.WidthRange = (function() { 
    var obj = {}; 
    return { 
    getObj: function() {return obj;} 
    , add: function (key, data) { 
     obj[key] = data; 
     return this; // enabling chaining 
     } 
    } 
})(); 

// Usage (using chaining calls): 
WidthRange.add(66, {foo: true}) 
.add(67, {bar: false}) 
.add(69, {baz: 'maybe', bork:'absolutely'}); 

var obj = WidthRange.getObj(); 
for (var prop in obj) { 
    console.log(obj[prop]); 
} 
18

如果你正在做的任何类型的数组/集合操作或检查,我强烈建议使用Underscore.js。它很小,测试良好,可以为你节省几天/几周/年的javascript头痛。下面是它的按键功能:

检索对象的属性的所有名称。

_.keys({one : 1, two : 2, three : 3}); 
=> ["one", "two", "three"] 
0

我写了一个什么样的功能使用对象的每个实例(数组是那些)工作正常。

Object.prototype.toArray = function() 
{ 
    if(!this) 
    { 
     return null; 
    } 

    var c = []; 

    for (var key in this) 
    { 
     if ((this instanceof Array && this.constructor === Array && key === 'length') || !this.hasOwnProperty(key)) 
     { 
      continue; 
     } 

     c.push(this[key]); 
    } 

    return c; 
}; 

用法:

var a = [ 1, 2, 3 ]; 
a[11] = 4; 
a["js"] = 5; 

console.log(a.toArray()); 

var b = { one: 1, two: 2, three: 3, f: function() { return 4; }, five: 5 }; 
b[7] = 7; 

console.log(b.toArray()); 

输出:

> [ 1, 2, 3, 4, 5 ] 
> [ 7, 1, 2, 3, function() { return 4; }, 5 ] 

它可以是对任何人是有用的。

+2

扩展一个你没有创建的原型是一个非常糟糕的主意,不管你认为它有多方便。 – doug65536 2013-12-11 01:39:39

54

可以用Object.keys(array)来查询字符串化的键。

+2

谢谢,正是我需要的。 – spazm 2014-02-20 23:04:13

+0

这将返回键作为字符串,而不是数字,只是让每个人都知道。 – 2017-11-01 13:36:36

0

... ????

或者,如果您想要使用的项目列表...

var range = [46, 66, 90] 
    , widthRange=[] 
    , write=[]; 

    widthRange[46] = { min:0, max:52 }; 
    widthRange[66] = { min:52, max:70 }; 
    widthRange[90] = { min:70, max:94 }; 

for(var x=0; x<range.length; x++){var key, wr; 

    key = range[x]; 

    wr = widthRange[key] || false; 

    if(wr===false){continue;} 

    write.push(['key: #',key, ', min: ', wr.min, 'max:', wr.max].join('')); 

    } 
2

说你的阵列看起来像 arr = [ { a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }, { a: 7, b: 8, c: 9 } ](或其他可能的键),你可以做

arr.map((o) => { 
    return Object.keys(o) 
}).reduce((prev, curr) => { 
    return prev.concat(curr) 
}).filter((col, i, array) => { 
    return array.indexOf(col) === i 
}); 

["a", "b", "c"]

2
widthRange.map(function(_, i) { return i }); 

widthRange.map((_, i) => i);