Como percorrer uma matriz contendo objetos e acessar suas propriedades


188

Eu quero percorrer os objetos contidos em uma matriz e alterar as propriedades de cada um. Se eu fizer isso:

for (var j = 0; j < myArray.length; j++){

console.log(myArray[j]);

}

O console deve exibir todos os objetos da matriz, certo? Mas, na verdade, ele exibe apenas o primeiro objeto. se eu consolar o log fora do loop, todos os objetos aparecerão, de modo que definitivamente haverá mais.

Enfim, aqui está o próximo problema. Como acesso, por exemplo, Object1.x na matriz, usando o loop?

for (var j = 0; j < myArray.length; j++){

console.log(myArray[j.x]);

}

Isso retorna "indefinido". Novamente, o log do console fora do loop diz que todos os objetos têm valores para "x". Como faço para acessar essas propriedades no loop?

Em outros lugares, fui recomendado o uso de matrizes separadas para cada uma das propriedades, mas quero garantir que eu tenha esgotado essa avenida primeiro.

Obrigado!


2
Você pode postar uma amostra da sua matriz? O primeiro trecho de código parece correto.
Sirko 18/05

jé um número Você o definiu na parte superior do seu loop.

2
Talvez myArraynão seja realmente apenas uma matriz, afinal?
Techfoobar

precisamos de mais informações sobre como myArray é construído
bgusach

Com todas as respostas a seguir e com uma resposta aceita, ninguém explica por que o problema ocorre e como resolvê-lo com o loop for. #forEachtrabalho. Mas a questão era sobre loop.
FreeLightman

Respostas:


341

Use forEach é uma função de matriz interna. Array.forEach():

yourArray.forEach(function (arrayItem) {
    var x = arrayItem.prop1 + 2;
    console.log(x);
});

2
feliz em help..Javascript está se tornando muito cool..plus o forEach é muito melhor e mais fácil de ler os laços complexos ..
Dory Sidom

3
Receio que forEachnão seja suportado no IE 9. Não me culpe! O produto do meu empregador dá suporte a isso!
fatCop

1
@DoryZidon: forEach não suporta pausa ou stop - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Ankur Loriya

2
Observe que é importante que você realmente tenha uma matriz. Se você obteve yourArrayalgo assim, document.getElementsByClassNameseria uma HTMLCollection, não uma matriz. Então essa pergunta pode ser útil.
J0ANMM 4/17

Nota: forEachestá bloqueando e não suporta await. O for...ofloop será.
PotatoFarmer 17/01

107

Alguns casos de uso de loop através de uma matriz da maneira de programação funcional em JavaScript:

1. Basta percorrer uma matriz

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

Nota: Array.prototype.forEach () não é uma maneira funcional, estritamente falando, pois a função que assume como parâmetro de entrada não deve retornar um valor, que, portanto, não pode ser considerado como uma função pura.

2. Verifique se algum dos elementos de uma matriz passa em um teste

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. Transforme em uma nova matriz

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

Nota: O método map () cria uma nova matriz com os resultados da chamada de uma função fornecida em todos os elementos da matriz de chamada.

4. Resuma uma propriedade específica e calcule sua média

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. Crie uma nova matriz com base no original, mas sem modificá-lo

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. Conte o número de cada categoria

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. Recupere um subconjunto de uma matriz com base em critérios específicos

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

Nota: O método filter () cria uma nova matriz com todos os elementos que passam no teste implementado pela função fornecida.

8. Classifique uma matriz

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

insira a descrição da imagem aqui

9. Encontre um elemento em uma matriz

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

insira a descrição da imagem aqui

O método Array.prototype.find () retorna o valor do primeiro elemento na matriz que satisfaz a função de teste fornecida.

Referências


1
Esta é uma referência fantástica - é original para esta pergunta ou você tem algo como esse hospedado em outro lugar?
Salvatore

Resposta muito bem explicada e completa, obrigado por contribuir.
Erica Summers

oi, se eu quero mostrar todo o nome e depois fazer a comparação, você sabe como fazer isso?
Dipgirl 27/07/19

@dipgirl, é algo como abaixo? const people = [ {name: "john", age:23}, {name: "john", age:43}, {name: "jim", age:101}, {name: "bob", age:67} ]; const sortByAge = people.map(p => { console.log(p.name) return p }).sort(function (p1, p2) { return p1.age - p2.age; }); console.log(sortByAge);
Yuci

1
Parabéns pela 100ª votação :)
Syed

46

Você pode usar um loop for..of para fazer loop sobre uma matriz de objetos.

for (let item of items) {
    console.log(item); // Will display contents of the object inside the array
}

Uma das melhores coisas dos for..ofloops é que eles podem iterar mais do que apenas matrizes. Você pode iterar sobre qualquer tipo de iterável, incluindo mapas e objetos. Certifique-se de usar um transpiler ou algo como TypeScript se precisar oferecer suporte a navegadores mais antigos.

Se você deseja iterar sobre um mapa, a sintaxe é basicamente a mesma que a anterior, exceto que lida com a chave e o valor.

for (const [key, value] of items) {
  console.log(value);
}

Eu uso for..ofloops para praticamente todo tipo de iteração que faço em Javascript. Além disso, uma das coisas mais legais é que eles também trabalham com async / waitit.


29
for (var j = 0; j < myArray.length; j++){
  console.log(myArray[j].x);
}

Essa é apenas a solução para a segunda pergunta, no entanto.
Sirko

18

Aqui está um exemplo de como você pode fazê-lo :)

var students = [{
    name: "Mike",
    track: "track-a",
    achievements: 23,
    points: 400,
  },
  {
    name: "james",
    track: "track-a",
    achievements: 2,
    points: 21,
  },
]

students.forEach(myFunction);

function myFunction(item, index) {
  for (var key in item) {
    console.log(item[key])
  }
}


como você obteria o valor da trackpropriedade para cada elemento e atribuiria a uma variável para usar ou interpolar em outra parte do código?
precisa

7

Fazer um loop através de uma matriz de objetos é uma funcionalidade bastante fundamental. Isto é o que funciona para mim.

var person = [];
person[0] = {
  firstName: "John",
  lastName: "Doe",
  age: 60
};

var i, item;

for (i = 0; i < person.length; i++) {
  for (item in person[i]) {
    document.write(item + ": " + person[i][item] + "<br>");
  }
}


6

myArray[j.x] está logicamente incorreto.

Use em (myArray[j].x);vez disso

for (var j = 0; j < myArray.length; j++){
  console.log(myArray[j].x);
}

@ Cyborgx37 Oh .. quero dizer jx é tratado como um nome de variável incorreto.
Vivek SADH

5

É realmente simples usar o método forEach desde o ES5 +. Você pode alterar diretamente cada propriedade de cada objeto em sua matriz.

myArray.forEach(function (arrayElem){ 
  arrayElem = newPropertyValue;
});

Se você deseja acessar uma propriedade específica em cada objeto:

myArray.forEach(function (arrayElem){ 
      arrayElem.nameOfYourProperty = newPropertyValue;
    });

4

Aqui está outra maneira de iterar através de uma matriz de objetos (você precisa incluir a biblioteca jQuery no seu documento para isso).

$.each(array, function(element) {
  // do some operations with each element... 
});

1
Sua resposta está faltando informações críticas sobre a necessidade de carregar a biblioteca jQuery para usar o $.eachmétodo
Matthew Morek

4

Isso funcionaria. Looping array completo (yourArray). Em seguida, faça um loop pelas propriedades diretas de cada objeto (eachObj).

yourArray.forEach( function (eachObj){
    for (var key in eachObj) {
        if (eachObj.hasOwnProperty(key)){
           console.log(key,eachObj[key]);
        }
    }
});

2

Iteração de objeto de matriz, usando jQuery, (use o segundo parâmetro para imprimir a sequência).

$.each(array, function(index, item) {
       console.log(index, item);
});

2

var c = {
    myProperty: [
        { name: 'this' },
        { name: 'can' },
        { name: 'get' },
        { name: 'crazy' }
    ]
};

c.myProperty.forEach(function(myProperty_element) {
    var x = myProperty_element.name;
    console.log('the name of the member is : ' + x);
})

Essa é uma das maneiras pelas quais consegui alcançá-lo.


1

A resposta aceita usa a função normal. Então, postando o mesmo código com pequenas modificações usando a função de seta no forEach

  yourArray.forEach(arrayItem => {
      var x = arrayItem.prop1 + 2;
      console.log(x);
  });

Também em $ .each você pode usar a função de seta como abaixo

 $.each(array, (item, index) => {
       console.log(index, item);
 });

1

const jobs = [
    {
        name: "sipher",
        family: "sipherplus",
        job: "Devops"
    },
    {
        name: "john",
        family: "Doe",
        job: "Devops"
    },
    {
        name: "jim",
        family: "smith",
        job: "Devops"
    }
];

const txt = 
   ` <ul>
        ${jobs.map(job => `<li>${job.name} ${job.family} -> ${job.job}</li>`).join('')}
    </ul>`
;

document.body.innerHTML = txt;

Cuidado com as costas Carrapatos (`)


0

Isso pode ajudar alguém. Talvez seja um bug no Node.

var arr = [ { name: 'a' }, { name: 'b' }, { name: 'c' } ];
var c = 0;

Isso não funciona:

while (arr[c].name) { c++; } // TypeError: Cannot read property 'name' of undefined

Mas isso funciona ...

while (arr[c]) { c++; } // Inside the loop arr[c].name works as expected.

Isso funciona também ...

while ((arr[c]) && (arr[c].name)) { c++; }

MAS simplesmente reverter a ordem não funciona. Acho que há algum tipo de otimização interna aqui que quebra o Node.

while ((arr[c].name) && (arr[c])) { c++; }

O erro diz que a matriz é indefinida, mas não é: - / Node v11.15.0

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.