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!

FlyingLizard
fonte
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);
});
Dory Zidon
fonte
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

Yuci
fonte
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.

Dwayne Charrington
fonte
29
for (var j = 0; j < myArray.length; j++){
  console.log(myArray[j].x);
}
Thierry
fonte
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])
  }
}

Puyi Severino
fonte
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>");
  }
}

MangoPapa7
fonte
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);
}
Vivek Sadh
fonte
@ 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;
    });
julien bouteloup
fonte
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... 
});
Partha Roy
fonte
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]);
        }
    }
});
sangamkumar91
fonte
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);
});
em
fonte
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.

Gurunath Rao
fonte
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);
 });
Hemadri Dasari
fonte
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 (`)

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

PJ Brunet
fonte