简体   繁体   English

JavaScript 关联数组上的 foreach 循环 object

[英]JavaScript foreach loop on an associative array object

Why is my for for-each loop not iterating over my JavaScript associative array object?为什么我的 for-each 循环没有遍历我的 JavaScript 关联数组 object?

// Defining an array
var array = [];

// Assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";

// Expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

jQuery each() could be helpful: https://api.jquery.com/jQuery.each/ jQuery each()可能会有帮助: https://api.jquery.com/jQuery.each/

The .length property only tracks properties with numeric indexes (keys). .length属性仅跟踪具有数字索引(键)的属性。 You're using strings for keys.您正在使用字符串作为键。

You can do this:你可以这样做:

var arr_jq_TabContents = {}; // no need for an array

arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;

for (var key in arr_jq_TabContents) {
    console.log(arr_jq_TabContents[key]);
}

To be safe, it's a good idea in loops like that to make sure that none of the properties are unexpected results of inheritance:为了安全起见,在这样的循环中确保没有任何属性是继承的意外结果是一个好主意:

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}

edit — it's probably a good idea now to note that the Object.keys() function is available on modern browsers and in Node etc. That function returns the "own" keys of an object, as an array:编辑——现在注意到Object.keys()函数在现代浏览器和 Node 等中可用可能是个好主意。该函数返回对象的“自己的”键,作为数组:

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);

The callback function passed to .forEach() is called with each key and the key's index in the array returned by Object.keys() .传递给.forEach()的回调函数使用Object.keys()返回的数组中的每个键和键的索引调用。 It's also passed the array through which the function is iterating, but that array is not really useful to us;它还传递了函数迭代的数组,但该数组对我们来说并没有什么用; we need the original object .我们需要原始对象 That can be accessed directly by name, but (in my opinion) it's a little nicer to pass it explicitly, which is done by passing a second argument to .forEach() — the original object — which will be bound as this inside the callback.这可以通过名称直接访问,但是(在我看来)显式传递它会更好一些,这是通过将第二个参数传递给.forEach() ——原始对象——将在回调中绑定为this来完成的. (Just saw that this was noted in a comment below.) (刚刚看到在下面的评论中指出了这一点。)

This is very simple approach.这是非常简单的方法。 The advantage is you can get keys as well:优点是您也可以获得密钥:

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}

For ES6:对于 ES6:

array.forEach(value => {
  console.log(value)
})

For ES6 (if you want the value, index and the array itself):对于 ES6(如果你想要值、索引和数组本身):

array.forEach((value, index, self) => {
  console.log(value, index, self)
})

If Node.js or the browser support Object.entries() , it can be used as an alternative to using Object.keys() ( Pointy's answer ).如果 Node.js 或浏览器支持Object.entries() ,它可以用作使用Object.keys()的替代方法( Pointy 的回答)。

 const h = { a: 1, b: 2 }; Object.entries(h).forEach(([key, value]) => console.log(value)); // logs 1, 2

In this example, forEach uses destructuring assignment of an array.在此示例中, forEach使用数组的解构赋值

There are some straightforward examples already, but I notice from how you've worded your question that you probably come from a PHP background, and you're expecting JavaScript to work the same way -- it does not.已经有一些简单的示例,但我从您对问题的措辞中注意到,您可能来自 PHP 背景,并且您期望 JavaScript 以相同的方式工作 - 事实并非如此。 A PHP array is very different from a JavaScript Array . PHP array与 JavaScript Array非常不同。

In PHP, an associative array can do most of what a numerically-indexed array can (the array_* functions work, you can count() it, etc.).在 PHP 中,关联数组可以完成数字索引数组的array_*功能( array_*函数可以工作,您可以对其进行count()等)。 You simply create an array and start assigning to string indexes instead of numeric.您只需创建一个数组并开始分配给字符串索引而不是数字。

In JavaScript, everything is an object (except for primitives: string, numeric, boolean), and arrays are a certain implementation that lets you have numeric indexes.在 JavaScript 中,一切都是对象(原始类型除外:字符串、数字、布尔值),数组是一种特定的实现,可以让您拥有数字索引。 Anything pushed to an array will affect its length , and can be iterated over using Array methods ( map , forEach , reduce , filter , find , etc.) However, because everything is an object, you're always free to simply assign properties, because that's something you do to any object.任何推送到数组的东西都会影响它的length ,并且可以使用 Array 方法( mapforEachreducefilterfind等)进行迭代。但是,因为一切都是一个对象,所以你总是可以自由地简单地分配属性,因为这是你对任何对象所做的事情。 Square-bracket notation is simply another way to access a property, so in your case:方括号表示法只是访问属性的另一种方式,因此在您的情况下:

array['Main'] = 'Main Page';

is actually equivalent to:实际上相当于:

array.Main = 'Main Page';

From your description, my guess is that you want an 'associative array', but for JavaScript, this is a simple case of using an object as a hashmap.根据您的描述,我的猜测是您想要一个“关联数组”,但对于 JavaScript,这是使用对象作为哈希图的简单情况。 Also, I know it's an example, but avoid non-meaningful names that only describe the variable type (eg array ), and name based on what it should contain (eg pages ).另外,我知道这是一个例子,但避免只描述变量类型(例如array )的无意义名称,以及基于它应该包含的内容(例如pages )的名称。 Simple objects don't have many good direct ways to iterate, so often we'll turn then into arrays first using Object methods ( Object.keys in this case -- there's also entries and values being added to some browsers right now) which we can loop.简单的对象没有很多好的直接迭代方法,所以我们通常会首先使用Object方法(在本例中为Object.keys —— 现在还有entriesvalues被添加到某些浏览器中),我们将首先将其转换为数组。可以循环。

// Assigning values to corresponding keys
const pages = {
  Main: 'Main page',
  Guide: 'Guide page',
  Articles: 'Articles page',
  Forum: 'Forum board',
};

Object.keys(pages).forEach((page) => console.log(page));

arr_jq_TabContents[key]将数组视为 0 索引形式。

Here is a simple way to use an associative array as a generic Object type:这是使用关联数组作为通用对象类型的简单方法:

 Object.prototype.forEach = function(cb){ if(this instanceof Array) return this.forEach(cb); let self = this; Object.getOwnPropertyNames(this).forEach( (k)=>{ cb.call(self, self[k], k); } ); }; Object({a:1,b:2,c:3}).forEach((value, key)=>{ console.log(`key/value pair: ${key}/${value}`); });

This is (essentially) incorrect in most cases:在大多数情况下,这(基本上)是不正确的:

var array = [];
array["Main"] = "Main page";

That creates a non-element property on the array with the name Main .这会在名为Main的数组上创建一个非元素属性。 Although arrays are objects, normally you don't want to create non-element properties on them.尽管数组是对象,但通常您不想在它们上创建非元素属性。

If you want to index into array by those names, typically you'd use a Map or a plain object, not an array.如果array这些名称索引array ,通常会使用Map或普通对象,而不是数组。

With a Map (ES2015+), which I'll call map because I'm creative:使用Map (ES2015+),我将其称为map因为我很有创意:

let map = new Map();
map.set("Main", "Main page");

you then iterate it using the iterators from its values , keys , or entries methods, for instance:然后使用它的valueskeysentries方法中的迭代器对其进行迭代,例如:

for (const value of map.values()) {
    // Here, `value` will be `"Main page"`, etc.
}

Using a plain object, which I'll creatively call obj :使用一个普通对象,我创造性地将其称为obj

let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`

you'd then iterate its contents using Object.keys , Object.values , or Object.entries , for instance:然后您将使用Object.keysObject.valuesObject.entries迭代其内容,例如:

for (const value of Object.values(proches_X)) {
    // Here, `value` will be `"Main page"`, etc.
}

It seems like almost every answer is not what was asked at the very first place.似乎几乎每个答案都不是最初提出的问题。

It's seems bit off that foreach-loop does not work. foreach-loop 不起作用似乎有点不对劲。 and simple for-loop will not work as well because length property will be zero in case of associative arrays(one of the fallback).并且简单的 for 循环将无法正常工作,因为在关联数组(后备之一)的情况下,长度属性将为零。 but for-in do the thing for associative array但是 for-in 为关联数组做事

 // Defining an array var array = []; // Assigning values to corresponding keys array["Main"] = "Main page"; array["Guide"] = "Guide page"; array["Articles"] = "Articles page"; array["Forum"] = "Forum board"; // Expected: loop over every item, // yet it logs only "last" assigned value - "Forum" for (var index in array) { console.log(index,array[index]); }

 var obj = { no: ["no", 32], nt: ["no", 32], nf: ["no", 32, 90] }; count = -1; // Which must be a static value for (i in obj) { count++; if (obj.hasOwnProperty(i)) { console.log(obj[i][count]) }; };

In this code I used the brackets method for call values in an array because it contained an array.在这段代码中,我使用括号方法调用数组中的值,因为它包含一个数组。 However, briefly the idea which a variable i has a key of property and with a loop called both values of the associative array.然而,简单地说,变量i有一个属性键和一个循环,称为关联数组的两个值。

It is the perfect method.这是完美的方法。

You can do this:你可以这样做:

var array = [];

// Assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";


array.forEach(value => {
    console.log(value)
})

 

Use numeric keys. 使用数字键。 length on an Array only tracks numeric keys. Array上的length仅跟踪数字键。 Use Object s or Map s for key-value pairs. ObjectMap用作键值对。

var array = [];

// assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";

for (var i = 0; i < array.length; i++) {
    console.log(i); //0 1 2 3
    //OR:
    console.log(array[i]);
}

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

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