2017-07-02 98 views
1

我无法理解遍历数组与迭代对象属性之间的区别。在对象的属性和数组之间迭代有什么区别Javascript

是什么区别:

for (key in object) { 
DO THIS 
} --> for objects 

for (var i = 0 ; i<array.length ; i++) { 
DO THIS 
} --> for arrays 

如果我想将对象值的特性中的阵列相比,可予同时通过对象迭代,并该数组在相同的功能。例如,像这样:

for (var key in object){ 
if (object.hasOwnProperty(key)){ 
    for (i=0 ; i<array.length; i++){ 
    if (object[key] === array[i]){ 
    filteredKeys[key] = object [key]} 

我的最终目标是编写一个函数,它接受一个对象和按键的排列,并返回一个新的对象,只有在数组中的键。

+0

认为你的意思是代替if。无论如何,你是问一个数组for循环和for-in循环之间的区别循环对象的可枚举属性? – Li357

+0

谢谢,是的,我的意思是(var i = 0 ...),编辑我的问题。是的,如果我想将数组中的值与对象中的属性进行比较,询问两者之间有什么区别以及是否将两者都包含在同一个函数中。 – Ana

回答

0

你必须明白的是,数组只是一些特殊的对象,它们的属性是数字(表示索引),值指示了这些索引处的元素 - 它们具有与任何对象一样的键和值。随着for循环是这样的:

for(var i = 0; i < arr.length; i++) { 
    arr[i]; //iterating through the array and accessing each element 
} 

你只是访问数字键像任何其他目的,只是通过bracket notation因为arr.0是无效的语法。现在使用for ... in循环,您只需遍历对象的枚举属性即可。正如我所说的,数组的索引(意思是0,1,2等)只是数组对象的关键字!因此,对于环上面并与此相同:

for(var i in arr) { 
    arr[i]; 
} 

由于该阵列的索引是键,此迭代通过键(索引),从而可以访问数组的元素。


为了解决您的其他问题 - 你可以通过对象以相同的循环迭代不是一个数组,如果他们有不同的密钥。数组以数字索引作为键进行排序,对象的键可以是任何东西。它们的键不一定相同,因此从数组和对象访问该键不会产生正确的结果。

相反,如果你想从基于对象过滤掉某些键,如果他们在一个数组或没有,请尝试以下操作:

function filterKeysByArray(object, keys) { 
    return keys.reduce((filteredObj, key) => { 
    if(object.hasOwnProperty(key)) { 
     filteredObj[key] = object[key]; 
    } 
    return filteredObj; 
    }, {}); 
} 

这样就完全避免嵌套的for循环。它只遍历传递数组中的键并将其减少到单个对象,即过滤对象。它检查对象是否具有由该键指定的属性,如果是,则将其添加到过滤的对象。

+0

感谢您澄清重新对象/数组!对于另一个问题,这不完全是我所指的 - 将编辑我的问题来澄清。 – Ana

+0

@Ana Ahh,我明白了。在这种情况下,你不能真正消除第二个循环,因为数组循环循环遍历属性0,1,2等,而for-in循环遍历对象的键,这些键不一定是0,1, 2等,但你可以用ES6代码缩短它。 – Li357

+0

@Ana我用示例实现更新了我的答案。 – Li357

0

对象和数组在JavaScript中基本上是不同的数据结构。对象是键值对的集合,而数组是有序的数据列表。

迭代通过对象键不同于迭代数组,因为您正在访问不同类型的数据结构中的数据。

我的最终目标是编写一个函数,它接受一个对象和一个键数组,并返回一个只有数组中的键的新对象。

这可以通过做这样的事情来完成:

function filterObject(obj, keys) { 
    var newObj = {}; 
    for (var i = 0; i < keys.length; i++) { 
    if (keys[i] in obj) { 
     newObj[keys[i]] = obj[keys[i]]; 
    } 
    } 
    return newObj; 
} 

例如,调用filterObject({'one': 1, 'two': 2}, ['one', 'three'])会产生的结果{'one': 1}

+0

对不起,我的措辞有点不清楚。我的意思是新对象只会返回数组中找到的键和原始对象,而不是数组中的所有键。 例如,如果对象具有属性名称和年龄。数组有[“名称”,“职业”],我只希望我的新对象包含属性名称和相应的值。 – Ana

+0

是的,你可以确保新对象只包含原始对象中的键,方法是在将值添加到新对象之前向循环中添加一个附加条件。我相应地修改了我的答案。 –

+0

但是在这种情况下,'keys'没有被定义,这是我在我的函数中没有包含“for(var keys in object)”的问题。 – Ana

相关问题