J. Adam Connor
J. Adam Connor

Reputation: 1734

Populate Object with Loop

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

Answers (1)

Nina Scholz
Nina Scholz

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

Related Questions