Home > database >  Typescript / Cypress: How to use forEach loop through two Objects?
Typescript / Cypress: How to use forEach loop through two Objects?

Time:03-17

I would like to implement a function and use in there a forEach to iterate through two objects. I have to compare both values per iteration.

Example / Idea:

const id = {a:'A2', b: 'B1', c:'C3'};
const name = {maria:'Maria',josef:'Josef',moses:'Moses'};

Object.values(id, name).forEach((ID, NAME) => {
   cy.contains(ID);
   cy.contains(NAME);
});

If I use two forEach loopslike this:

Object.values(id).forEach((ID) => {
Object.values(name).forEach((NAME) => {
       cy.contains(ID);
       cy.contains(NAME);
    });
});

logically it doesn't iterate evenly.

Thank you for you help!

CodePudding user response:

cy.contains(ID) and cy.contains(NAME) search for independent elements - you can loop independently.

Object.values(id).forEach((ID) => {
  cy.contains(ID);
})

Object.values(name).forEach((NAME) => {
  cy.contains(NAME);
})

Unless you want to check both id and name on the same element, in which case cy.contains(...) is too simple.

You can correlate values via the index

Object.values(id).forEach((ID, index) => {

  const NAME = Object.values(name)[index]
  cy.contains(`#${ID}`, NAME);  // get element with id of ID and text of NAME
                                // e.g <div id="A2">Maria</div>

})

By the way, it's better to use plural form for lists and single form for list items, rather than lower case and upper case.

I kept your convention to make the change clearer, but consider names and name, ids and id.

CodePudding user response:

Beware that relying on property order is asking for trouble. Property order is complex. It depends on how the object was created and the names of the properties. For example, the properties in these two objects are in a different order. Some examples of that:

// The properties in these objects are in a *different* order from one another
const ex1a = {x: 1, y: 2};
const ex1b = {y: 2, x: 1};
console.log(sameOrder(ex1a, ex1b)); // false

// Less obviously, the order of the properties in these two objects
// **is the same**:
const ex2a = {"2": 1, x: 2};
const ex2b = {x: 2, "2": 1};
console.log(sameOrder(ex2a, ex2b)); // true

// The order of these is the same:
const ex3a = {};
const ex3b = {a: 1, b: 2};
ex3a.a = 1;
ex3a.b = 2;
console.log(sameOrder(ex3a, ex3b)); // true

// But the order of these is different:
const ex4a = {};
const ex4b = {a: 1, b: 2};
ex4a.b = 2;
ex4a.a = 1;
console.log(sameOrder(ex4a, ex4b)); // false

// And so on.

function sameOrder(a, b) {
    const anames = Object.keys(a);
    const bnames = Object.keys(b);
    return anames.length === bnames.length &&
        anames.every((aname, index) => aname === bnames[index]);
}

But if you don't care about the order and only care about the values, just get the values as arrays and then use a simple loop:

const idValues = Object.values(id);
const nameValues = Object.values(name);
for (let i = 0, max = Math.max(idValues.length, nameValues.length); i < max;   i) {
    const idValue = idValues[i];
    const nameValue = nameValues[i];
    // ...do something with `idValue` and `nameValue`...
    // Note that if the arrays aren't the same length, one of those will be `undefined`
    // once the loop has gone beyond the length of the array it came from.
}

CodePudding user response:

Thank you to all!

With your examples I solved my problem.

solution:

const names = Object.values(name);
Object.values(id).forEach((ID, index) => {
   cy.contains(ID);
   cy.contains(names[index]);
});
  • Related