Як провести цикл через масив, що містить об'єкти, та отримати доступ до їх властивостей


188

Я хочу переглядати об'єкти, що містяться в масиві, і змінювати властивості кожного з них. Якщо я це роблю:

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

console.log(myArray[j]);

}

Консоль повинна містити кожен об'єкт у масиві, правда? Але насправді він відображає лише перший об’єкт. якщо я консолірую журнал масиву поза циклом, всі об'єкти з'являються, так що там, безумовно, більше.

У всякому разі, ось наступна проблема. Як я можу отримати доступ, наприклад, до Object1.x у масиві, використовуючи цикл?

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

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

}

Це повертається "невизначено". Знову журнал консолі поза циклом підказує мені, що всі об'єкти мають значення "x". Як отримати доступ до цих властивостей у циклі?

Мені рекомендували в іншому місці використовувати окремі масиви для кожного з властивостей, але я хочу переконатися, що спочатку я вичерпав цей проспект.

Дякую!


2
Чи можете ви опублікувати зразок свого масиву? Перший фрагмент коду здається правильним.
Сірко

j- це число. Ви визначили це у верхній частині петлі.

2
Може, myArrayце насправді не просто масив ??
технофобар

нам потрібна додаткова інформація про те, як побудований myArray
bgusach

З усіма наступними відповідями та з прийнятою відповіддю ніхто не пояснює, чому виникає проблема та як її вирішити за допомогою циклу. #forEachпрацює. Але питання стосувалося циклу.
FreeLightman

Відповіді:


341

Використовуйте дляEach свою вбудовану функцію масиву. Array.forEach():

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

2
Рада допомогти. Яваскрутт стає досить крутим .. рясніть forEach набагато краще і простіше читати складні петлі ..
Dory Zidon

3
Боюся, це forEachне підтримується в IE 9. Не звинувачуйте мене! Продукт мого роботодавця дає підтримку в цьому!
fatCop

1
@DoryZidon: forEach не підтримує перерву чи зупинку - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ankur Loriya

2
Зауважте, що важливо, щоб у вас дійсно був масив. Якщо ви отримали yourArrayщось подібне, document.getElementsByClassNameце був би HTMLCollection, а не масив. Тоді це питання може бути корисним.
J0ANMM

Примітка: forEachблокується і не підтримує await. for...ofЦикл буде.
КартопляФермер

107

Деякі використовують випадки циклічного перегляду масиву функціональним способом програмування в JavaScript:

1. Просто проведіть масив через масив

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

Примітка: Array.prototype.forEach () не є функціональним способом, строго кажучи, оскільки функція, яку вона бере як вхідний параметр, не повинна повертати значення, що, таким чином, не може розглядатися як чиста функція.

2. Перевірте, чи будь-який з елементів масиву пройшов тест

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. Перетворення на новий масив

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

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

Примітка: Метод map () створює новий масив з результатами виклику наданої функції на кожному елементі викличного масиву.

4. Підсумуйте певну властивість та обчисліть її середнє значення

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. Створіть новий масив на основі оригіналу, але не змінюючи його

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. Порахуйте кількість кожної категорії

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. Отримайте підмножину масиву на основі конкретних критеріїв

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

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

Примітка. Метод filter () створює новий масив з усіма елементами, які проходять тест, реалізований наданою функцією.

8. Сортуйте масив

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

введіть тут опис зображення

9. Знайдіть елемент у масиві

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

введіть тут опис зображення

Метод Array.prototype.find () повертає значення першого елемента в масиві, що задовольняє наданій функції тестування.

Список літератури


1
Це фантастична довідка - це оригінал цього питання чи у вас щось подібне розміщено в іншому місці?
Сальваторе

Дуже добре пояснена і ґрунтовна відповідь, дякую за внесок.
Еріка Саммерс

привіт, якщо я хочу показати все ім'я, а потім порівняти, чи знаєте ви, як це зробити?
dipgirl

@dipgirl, це щось на кшталт нижче? 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);
Юйци

1
Вітаємо з 100-м голосом :)
Проведено

46

Ви можете використовувати цикл for..of для циклічного перегляду масиву об'єктів.

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

Одна з найкращих речей про for..of циклів - це те, що вони можуть перебирати більше, ніж просто масиви. Ви можете перебирати будь-який тип ітерабелів, включаючи карти та об’єкти. Переконайтеся, що ви використовуєте транспілер або щось на зразок TypeScript, якщо вам потрібна підтримка старих браузерів.

Якщо ви хотіли повторити карту, синтаксис багато в чому такий же, як і вище, за винятком того, що він обробляє і ключ, і значення.

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

Я використовую for..ofпетлі для майже всіх ітерацій, які я роблю в Javascript. Крім того, одна з найкрутіших речей - це те, що вони також працюють з асинхронізацією / очікуванням.



18

Ось приклад того, як це можна зробити :)

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


як би ви отримали значення trackвластивості для кожного елемента і призначили його змінній для використання або інтерполяції в іншій частині коду?
Chris22

7

Прокручування масиву об'єктів - це досить фундаментальна функціональність. Це те, що працює для мене.

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] є логічно неправильним.

Використовуйте (myArray[j].x);замість цього

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

@ Cyborgx37 О .. Я маю на увазі, що jx трактується як ім'я змінної, яке є неправильним.
Вівек Сад

5

Це дуже просто, використовуючи метод forEach з ES5 +. Ви можете безпосередньо змінити кожну властивість кожного об'єкта у своєму масиві.

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

Якщо ви хочете отримати доступ до певної властивості для кожного об’єкта:

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

4

Ось ще один спосіб ітерації через масив об’єктів (для цього вам потрібно включити бібліотеку jQuery).

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

1
У вашій відповіді відсутня важлива інформація про необхідність завантаження бібліотеки jQuery для використання $.eachметоду.
Меттью Морек

4

Це спрацювало б. Цикл ретельного масиву (yourArray). Потім проведіть цикл через прямі властивості кожного об'єкта (everyObj).

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

2

Масивуйте ітерацію об'єктів, використовуючи jQuery (використовуйте другий параметр для друку рядка).

$.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);
})

Це один із способів, як мені вдалося цього досягти.


1

Прийнята відповідь використовує звичайну функцію. Отже, розміщуючи той самий код з незначною модифікацією, використовуючи функцію стрілки на forEach

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

Також у $ .each ви можете використовувати функцію стрілки, як показано нижче

 $.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;

Будьте обережні щодо тильних кліщів (`)


0

Це може комусь допомогти. Можливо, це помилка в Node.

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

Це не працює:

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

Але це працює ...

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

Це теж працює ...

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

АЛЕ просто відмінити замовлення не працює. Я здогадуюсь, тут є якась внутрішня оптимізація, яка порушує Node.

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

Помилка каже, що масив не визначений, але це не так: - / Node v11.15.0

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.