简体   繁体   English

如何迭代Javascript中的数组键?

[英]How to iterate array keys in Javascript?

I have an array created with this code:我有一个用这段代码创建的数组:

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

I want to get each of the values 46, 66, 90 in a loop.我想在循环中获取每个值 46、66、90。 I tried for (var key in widthRange) but this gives me a whole bunch of extra properties (I assume they are functions on the object).我试过for (var key in widthRange)但这给了我一大堆额外的属性(我假设它们是对象上的函数)。 I can't use a regular for loop since the values are not sequential.我不能使用常规的 for 循环,因为值不是连续的。

You need to call the hasOwnProperty function to check whether the property is actually defined on the object itself (as opposed to its prototype), like this:您需要调用hasOwnProperty函数来检查该属性是否实际定义在对象本身(而不是其原型上),如下所示:

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

Note that you need a separate check for length .请注意,您需要单独检查length
However, you shouldn't be using an array here at all;但是,您根本不应该在这里使用数组; you should use a regular object.您应该使用常规对象。 All Javascript objects function as associative arrays.所有 Javascript 对象都用作关联数组。

For example:例如:

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

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

If you are doing any kind of array/collection manipulation or inspection I highly recommend using Underscore.js .如果您正在进行任何类型的数组/集合操作或检查,我强烈建议您使用Underscore.js It's small, well-tested and will save you days/weeks/years of javascript headache.它很小,经过充分测试,可以为您节省数天/数周/数年的 javascript 头痛。 Here is its keys function:这是它的按键功能:

Keys钥匙

Retrieve all the names of the object's properties.检索对象属性的所有名称。

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

Say your array looked like arr = [ { a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }, { a: 7, b: 8, c: 9 } ] (or possibly other keys) you could do假设你的数组看起来像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"]

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

You can't really get just the keys you've set because that's not how an Array works. 你真的不能只得到你设置的键,因为这不是 Array 的工作方式。 Once you set element 46, you also have 0 through 45 set too (though they're null). 设置元素 46 后,也设置了 0 到 45(尽管它们为空)。

You could always have two arrays:你总是可以有两个数组:

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

edit well it may be that I'm all wet here ...编辑好吧,可能是我在这里都湿了......

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

或者

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

Your original example works just fine for me:你原来的例子对我来说很好用:

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

Results in the browser (Firefox 3.6.2 on Windows XP):浏览器中的结果(Windows XP 上的 Firefox 3.6.2):

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

I think you should use an Object ( {} ) and not an array ( [] ) for this.我认为您应该为此使用 Object ( {} ) 而不是数组 ( [] )。

A set of data is associated with each key.一组数据与每个键相关联。 It screams for using an object.它为使用对象而尖叫。 Do:做:

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

Maybe some utility stuff like this can help:也许像这样的一些实用工具可以提供帮助:

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

To generate an Array from an Array's keys, use要从数组的键生成数组,请使用

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

The example above will give an array of 0 to 9. It is not exactly what you asked for but I hope this gives an insight into this method.上面的示例将给出 0 到 9 的数组。这不是您所要求的,但我希望这能让您深入了解此方法。

I wrote a function what works fine with every instance of Objects (Arrays are those).我写了一个函数,它适用于每个对象实例(数组就是那些)。

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

Usage:用法:

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

Output:输出:

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

It may be useful for anyone.它可能对任何人都有用。

... ???? ……???

Alternatively, if you have a list of items you want to use...或者,如果您有要使用的项目列表...

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

    }

Seems to work.似乎工作。

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

For your input data:对于您的输入数据:

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 }

Declarative approach:声明式方法:

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

Object.keys to get the keys, using parseInt to cast them as numbers. Object.keys获取键,使用parseInt将它们转换为数字。 filter to get only ones you want. filter以仅获取您想要的。 map to build an array from the original object of just the indices you're after, since Object.keys loses the object values. map以从您所追求的索引的原始对象构建一个数组,因为Object.keys丢失了对象值。

Debug:调试:

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

The question is pretty old, but nowadays you can use forEach, which is efficient and will retain the keys as numbers:这个问题已经很老了,但现在你可以使用 forEach,它很有效,并将键保留为数字:

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

This loops through widthRange and makes a new array with the value of the keys, and then filters out all sparce slots by only taking the values that are defined.这会循环遍历 widthRange 并使用键的值创建一个新数组,然后仅使用定义的值过滤掉所有的空槽。

(Bad idea, but for thorughness: If slot 0 was always empty, that could be shortened to filter(i=>i) or filter(Boolean) (坏主意,但为了彻底:如果插槽 0 始终为空,则可以缩短为filter(i=>i)filter(Boolean)

And, it may be less efficient, but the numbers can be cast with let keys = Object.keys(array).map(i=>i*1)而且,它可能效率较低,但可以使用let keys = Object.keys(array).map(i=>i*1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM