如何在 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),但它给了我一大堆额外的属性(我假设它们是对象上的函数)。我不能使用正则 for 循环,因为这些值不是顺序的。

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

实际上不能只获得已设置的键,因为 Array 不是这样工作的。一旦设置了元素46,也就设置了0到45(尽管它们是 null)。

你可以一直使用 数组:

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]]);
}

编辑 好吧,这可能是因为我全身湿透了..。

您需要调用 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 };

你最初的例子对我来说很有用:

<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>

浏览器中的结果(WindowsXP 上的 Firefox3.6.2) :

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

看起来有用。

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 />");
}

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

一组数据与每个键相关联,它强烈要求使用一个对象:

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]);
}

如果您正在进行任何类型的数组/集合操作或检查,我强烈推荐使用 下划线.js。它很小,经过了良好的测试,可以为您节省几天/几周/几年的 javascript 头痛。下面是它的关键功能:

钥匙

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

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

我写了一个函数,它可以很好地处理对象的每个实例(数组就是那些)。

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 ]

它可能对任何人都有用。

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

... ????

或者,如果您有一个要使用的项目列表..。

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(''));


}

假设你的阵列看起来像 你可以按 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"]

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

或者

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

输入数据:

let widthRange = new Array()
widthRange[46] = { min:0,  max:52 }
widthRange[61] = { min:52, max:70 }
widthRange[62] = { min:52, max:70 }
widthRange[63] = { min:52, max:70 }
widthRange[66] = { min:52, max:70 }
widthRange[90] = { min:70, max:94 }

宣言式方法:

const relevantKeys = [46,66,90]
const relevantValues = Object.keys(widthRange)
.filter(index => relevantKeys.includes(parseInt(index)))
.map(relevantIndex => widthRange[relevantIndex])

Object.keys获取密钥,使用 parseInt将它们转换为数字。 filter只得到你想要的。 由于 Object.keys丢失了对象值,所以只需要根据所需的索引从原始对象构建数组。

调试:

console.log(widthRange)
console.log(relevantKeys)
console.log(relevantValues)

这个问题已经很老了,但是现在你可以使用 forEach,它是高效的,并且可以保留键作为数字:

let keys = widthRange.map((v,k) => k).filter(i=>i!==undefined))

这个函数循环遍历 widthRange,并使用键的值创建一个新数组,然后通过仅获取定义的值来过滤掉所有空格槽。

(坏主意,但为了彻底: 如果槽0始终是空的,那么可以缩短为 filter(i=>i)filter(Boolean)

而且,它可能效率较低,但数字可以与 let keys = Object.keys(array).map(i=>i*1)铸造

若要从 Array 的键生成 Array,请使用

Array.from(Array(10).keys());

上面的示例将给出0到9的数组。这并不完全是您所要求的,但我希望这可以帮助您深入了解这种方法。