2010-03-24 124 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);