An array of objects is a list where each item is an object with named properties — for example a list of users, products or test results. It's the most common data shape in JavaScript, and in test automation you meet it constantly: API responses in Playwright or Postman, test data, and rows read from a table.
- How to create an array of objects and read its values
- Loop,
find,filter,map,someandevery - Sort by a property, total with
reduceand group by a field - Convert to and from JSON — and avoid the copy and comparison traps
Create an Array of Objects
const results = [
{ id: 1, name: 'Login with valid user', status: 'passed', durationMs: 1200 },
{ id: 2, name: 'Login with wrong password', status: 'failed', durationMs: 900 },
{ id: 3, name: 'Add item to cart', status: 'passed', durationMs: 2100 },
{ id: 4, name: 'Checkout as guest', status: 'skipped', durationMs: 0 },
];
console.log(results[0].name); // Login with valid user
Square brackets select the item (results[0]); a dot selects the property (.name).
All the Operations in One Example
Every common operation, run with Node.js 22:
// An array of objects: each object is one test result
const results = [
{ id: 1, name: 'Login with valid user', status: 'passed', durationMs: 1200 },
{ id: 2, name: 'Login with wrong password', status: 'failed', durationMs: 900 },
{ id: 3, name: 'Add item to cart', status: 'passed', durationMs: 2100 },
{ id: 4, name: 'Checkout as guest', status: 'skipped', durationMs: 0 },
];
// 1. Read a value
console.log('1.', results[0].name);
// 2. Loop over every object
for (const r of results) console.log('2.', r.id, r.status);
// 3. find: the first match (or undefined)
const firstFailed = results.find(r => r.status === 'failed');
console.log('3.', firstFailed.name);
// 4. filter: every match, as a new array
const passed = results.filter(r => r.status === 'passed');
console.log('4.', passed.length, 'passed');
// 5. map: turn each object into something else
console.log('5.', results.map(r => r.name));
// 6. some / every: yes-or-no questions about the whole array
console.log('6.', results.some(r => r.status === 'failed'), results.every(r => r.durationMs < 3000));
// 7. reduce: total time
const total = results.reduce((sum, r) => sum + r.durationMs, 0);
console.log('7.', total, 'ms in total');
// 8. sort by a property (copy first: sort() changes the original)
const slowest = [...results].sort((a, b) => b.durationMs - a.durationMs);
console.log('8.', slowest.map(r => `${r.id}:${r.durationMs}`).join(' '));
// 9. add, update and remove
results.push({ id: 5, name: 'Logout', status: 'passed', durationMs: 300 });
const cart = results.find(r => r.id === 3); cart.status = 'failed';
const withoutSkipped = results.filter(r => r.status !== 'skipped');
console.log('9.', results.length, 'results,', withoutSkipped.length, 'without skipped');
// 10. group by status
const byStatus = results.reduce((acc, r) => { (acc[r.status] ||= []).push(r.id); return acc; }, {});
console.log('10.', byStatus);
// 11. to and from JSON (API responses are usually arrays of objects)
const json = JSON.stringify(passed.map(({ id, name }) => ({ id, name })));
console.log('11.', json);
console.log('11.', JSON.parse(json)[1].name);
Output
1. Login with valid user
2. 1 passed
2. 2 failed
2. 3 passed
2. 4 skipped
3. Login with wrong password
4. 2 passed
5. [
'Login with valid user',
'Login with wrong password',
'Add item to cart',
'Checkout as guest'
]
6. true true
7. 4200 ms in total
8. 3:2100 1:1200 2:900 4:0
9. 5 results, 4 without skipped
10. { passed: [ 1, 5 ], failed: [ 2, 3 ], skipped: [ 4 ] }
11. [{"id":1,"name":"Login with valid user"},{"id":3,"name":"Add item to cart"}]
11. Add item to cart
| Method | Returns | Use it to |
|---|---|---|
for...of | — | Do something with every object |
find(fn) | The first matching object, or undefined | Get one item by id, name… |
filter(fn) | A new array of every match | Get all failed tests |
map(fn) | A new array of the same length | Pick one property, or reshape objects |
some(fn) / every(fn) | true / false | Check "any failed?" or "all under 3 s?" |
reduce(fn, start) | One value | Totals, counts, grouping |
sort(fn) | The same array, sorted | Order by a property (copy first!) |
findIndex(fn) | The index, or -1 | Find a position to update or remove |
Using It in Playwright API Tests
const response = await request.get('/api/users');
const users = await response.json(); // an array of objects
expect(users.length).toBeGreaterThan(0);
expect(users.some(u => u.email === 'admin@example.com')).toBeTruthy();
const admin = users.find(u => u.role === 'admin');
expect(admin).toBeDefined();
Common Mistakes
const a = [{ id: 1 }, { id: 2 }];
console.log('includes:', a.includes({ id: 1 })); // compares references, not contents
console.log('some:', a.some(o => o.id === 1));
const copy = [...a]; copy[0].id = 99; // spread copies the array, not the objects
console.log('original after editing the copy:', a[0].id);
const deep = structuredClone(a); deep[1].id = 42;
console.log('original after editing a deep copy:', a[1].id);
console.log('sort numbers as text:', [10, 9, 100].sort());
console.log('find with no match:', [{ id: 1 }].find(o => o.id === 5));
Output
includes: false
some: true
original after editing the copy: 99
original after editing a deep copy: 2
sort numbers as text: [ 10, 100, 9 ]
find with no match: undefined
includes()with an object returns false — objects are compared by reference, not contents. Fix:some(o => o.id === 1).- Spread copies the array, not the objects — editing
copy[0]changed the original. Fix:structuredClone(array)for a deep copy. sort()without a compare function sorts as text (10, 100, 9). Fix:sort((a, b) => a - b)or compare a property.sort()changes the original array. Fix: sort a copy:[...arr].sort(...)(ortoSorted()in newer engines).- Using
find()'s result without checking — it returnsundefinedwhen nothing matches, and.namethen throws a TypeError.
Practice Exercises
- From the results array, print the names of all failed tests.
- Calculate the average duration of passed tests.
- Group the results by status and print how many are in each group.
Key Takeaways
findreturns one item;filterandmapreturn new arrays;reducereturns one value.- Objects are compared by reference — use
some/findwith a property check. sort()sorts as text by default and changes the original array.
📚 Official documentation: MDN: Array · MDN: structuredClone()
Frequently Asked Questions
How do I find an object in an array by a property?
Use find: users.find(u => u.id === 3). It returns the first match or undefined.
How do I sort an array of objects by a property?
Pass a compare function: arr.sort((a, b) => a.age - b.age) for numbers, or (a, b) => a.name.localeCompare(b.name) for text. Sort a copy if you need the original order.
How do I check if an array of objects contains a value?
Use some: arr.some(o => o.email === "x@y.com"). includes() compares object references, so it returns false for a new object with the same contents.
How do I copy an array of objects?
[...arr] copies the array but shares the objects. Use structuredClone(arr) for a deep copy.
How do I convert an array of objects to JSON?
JSON.stringify(arr) turns it into a JSON string; JSON.parse(text) turns it back into an array of objects.