There's a vast argument wether knowing mathematics is essential to be able to learn Computer Science. I'd argue that it is, if you wish to implement any algorithms aside basic calculations.

Suppose you have two objects, using Person as the object, I create a new Person mike, and another Person sam. In previous posts I've talked about calculating deltas for the objects, but this time let's try something new - let's calculate how many twins Sam has, versus how many twins Mike has without using delta calculations.

Here's what you need to know about our Persons array, we have Mike and Sam - in this array we also have 20 other people; this makes 22 Persons. The simplest answer is to iterate on both of them comparing properties - but in this case we don't know the properties.

Magic Property Iteration

First, we would need to get into our outer array, Persons:

``````var Persons = [/**....**/];
var Twins   = [];
Persons.forEach(person => {

});
``````

Now that we're in Persons, we need to figure out what index Mike and Sam are - we cannot fully assume they are the first two indexes.

``````var Mike = {};
var Sam = {};
Persons.forEach(person => {
if( person.getName() === 'Mike' ) { Mike = person; }
else if( person.getName() === 'Sam' ) { Sam = person; }
});
``````

Now we don't care the position, we have Mike and Sam out of our array. Now let's iterate on the array again, this time finding property twins:

``````Persons.forEach(person => {
var props = Object.keys(person);
var m_props = Object.keys(Mike);
var s_props = Object.keys(Sam);
var similar = [];
props.forEach(prop => {
if( typeof m_props[prop] !== 'undefined' && Mike[prop] === person[prop] ) {
similar.push({ p: prop, u: Mike });
}
if( typeof s_props[prop] !== 'undefined' && Sam[prop] === person[prop] ) {
similar.push({ p: prop, u: Sam });
}
});
var m_count = 0;
var s_count = 0;
similar.forEach(index => {
if(index.u.getName() === 'Mike') {
m_count++;
} else if(index.u.getName() === 'Sam') {
s_count++;
}
});
Twins.push({ 'of': getWinner(m_count, s_count, Mike, Sam) });
});

function getWinner(l_count, r_count, l_obj, r_obj) {
var l = l_count > r_count;
if(l) {
return l_obj;
}
else {
return r_obj;
}
}
``````

This iteration we did above, we found dynamic properties, compared them to the ones we expect on our object, then we iterated on each, counting the number of times we shared the properties (twin properties) with the same values. We then ran getWinner function, which checked if the left's greater than the right, and it'll return either the left or right object depending on the count result, and push it into the Twins array.

Finally, we need to get the Twins array, and print everything out!

``````var doc = new DOMDocument(); // custom class
Twins.forEach(twin => {
var twin_of = twin.of.getName();
doc.writeNewAddedTwin('A twin of ' + twin_of + ' was found!');
});
``````

And there we have it, a simple magic iteration, comparison and pulling the relevant data out. You may be able to tell if you've read my article on delta signatures that this method of magic iteration is the longest, however, typically the most common way of doing it. In terms of readability, I find that delta comparison is better, likewise when iterating, you don't have to go 3/4 loops in, it only takes one loop and you've got your answer.

Thats all for now, hopefully you've learned something new today!

Mike

Senior Software Engineer, Labber, Sysadmin. I make things scale rapidly. Optimize everything.