Reputation: 1734
Consider the following model:
var threads = {
"thread1": {
"upvotes": {
"1": true,
"3": true,
"4": true,
"10": true
},
"downvotes": {
"2": true,
"5": true,
"8": true,
"9": true
}
},
"thread2": {
"upvotes": {
"1": true,
"3": true,
"7": true,
"10": true
},
"downvotes": {
"2": true,
"6": true,
"8": true,
"9": true
}
},
"thread3": {
"upvotes": {
"1": true,
"4": true,
"7": true,
"10": true
},
"downvotes": {
"2": true,
"5": true,
"8": true
}
}
}
I'd like to iterate over this model, getting a count of each instance in which each number in upvotes
coincides with each of the other numbers in upvotes
. I'm doing the following to achieve a crude approximation of this:
var us = 0;
var youObj = {};
var matchesObj = {};
members = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
var getAlignments = function(me, you) {
for (var thread in threads) {
if ((Object.keys(threads[thread].upvotes).includes(me)) && (Object.keys(threads[thread].upvotes).includes(you))) {
us++
}
}
if (us > 0) {
youObj[you] = us
matchesObj[me] = youObj
us = 0;
}
}
for (var i = 0; i < members.length; i++) {
var me = members[i]
for (var j = 0; j < members.length; j++) {
var you = members[j]
getAlignments(me, you)
}
}
console.log(matchesObj)
This logs the following to console:
{
'1': { '1': 3, '3': 2, '4': 2, '7': 2, '10': 3 },
'3': { '1': 3, '3': 2, '4': 2, '7': 2, '10': 3 },
'4': { '1': 3, '3': 2, '4': 2, '7': 2, '10': 3 },
'7': { '1': 3, '3': 2, '4': 2, '7': 2, '10': 3 },
'10': { '1': 3, '3': 2, '4': 2, '7': 2, '10': 3 }
}
As you can see, the child objects are all identical. The reason for this is obvious. The last object assigned to its parent in the loop overwrites the previous object. Each property key in the { '1': 3, '3': 2, '4': 2, '7': 2, '10': 3 }
object represents a number that coincides with '10'
in each thread's upvotes
object and each property value represents a count of these coincidences.
What I need is this type of list for each number that coincides with other numbers in upvotes
. This seems like such a basic problem, but I'm struggling with it right now.
Upvotes: 1
Views: 1710
Reputation: 386560
Why not use a double nested loop over the keys and get the count.
var threads = { thread1: { upvotes: { 1: true, 3: true, 4: true, 10: true }, downvotes: { 2: true, 5: true, 8: true, 9: true } }, thread2: { upvotes: { 1: true, 3: true, 7: true, 10: true }, downvotes: { 2: true, 6: true, 8: true, 9: true } }, thread3: { upvotes: { 1: true, 4: true, 7: true, 10: true }, downvotes: { 2: true, 5: true, 8: true } } },
result = {};
Object.keys(threads).forEach(function (k) {
Object.keys(threads[k].upvotes).forEach(function (l) {
result[l] = (result[l] || 0) + 1;
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Solution with pairs.
var threads = { thread1: { upvotes: { 1: true, 3: true, 4: true, 10: true }, downvotes: { 2: true, 5: true, 8: true, 9: true } }, thread2: { upvotes: { 1: true, 3: true, 7: true, 10: true }, downvotes: { 2: true, 6: true, 8: true, 9: true } }, thread3: { upvotes: { 1: true, 4: true, 7: true, 10: true }, downvotes: { 2: true, 5: true, 8: true } } },
result = {},
result2 = {};
Object.keys(threads).forEach(function (k) {
var keys = Object.keys(threads[k].upvotes);
keys.forEach(function (l) {
result[l] = (result[l] || 0) + 1;
result2[l] = result2[l] || {};
keys.forEach(function (m) {
if (l !== m) {
result2[l][m] = (result2[l][m] || 0) + 1;
}
});
});
});
console.log(result);
console.log(result2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2