Benedict Lewis
Benedict Lewis

Reputation: 2813

Find closest match between several arrays

I am creating a chat script, where a user can set their interests. When a user connects to the server their client sends the following JSON over WebSocket:

{"id": int, "hash": md5, "automessage": {...}, "interests": ["cars", "programming", "stackoverflow"]}

When the first connection is received it is pushed to a waiting array. Every time another connection starts it removes the last object from the array to 'pair' them together. What I now need to do is write a function so that when it receives the message it it looks at the interests value of all the objects in the waiting array and returns the object with the most common interests. For example, if the waiting array looks like this:

[
    {"id": int, "hash": md5, "automessage": {...}, "interests": ["cats", "animals", "cars"]},
    {"id": int, "hash": md5, "automessage": {...}, "interests": ["programming", "ssh", "stackoverflow"]},
    {"id": int, "hash": md5, "automessage": {...}, "interests": ["climbing", "football", "coffee"]}
]

Now when the above message is received it looks through the above array, and returns the object one with the most similar interests. So, in this example it would return {"id": int, "hash": md5, "automessage": {...}, "interests": ["programming", "ssh", "stackoverflow"]}.

If it cannot find any entries with similar interests, then the user should be added to the waiting list array.

I'm pretty stuck with this, so can anyone help?


Not really sure why the question got downvoted. Care to add a comment?

Upvotes: 1

Views: 159

Answers (2)

Raunak Kathuria
Raunak Kathuria

Reputation: 3225

DEMO

You can try this to find from the waiting list the best candidate, then if not found you can add it to

 var incoming = {
    "id": 'int',
        "hash": 'md5',
        "automessage": {},
        "interests": ["cars", "programming", "stackoverflow"],
};

var waiting_list = [{
    "id": 'int',
        "hash": 'md5',
        "automessage": {},
        "interests": ["cats", "animals", "cars"]
}, {
    "id": 'int',
        "hash": 'md5',
        "automessage": {},
        "interests": ["programming", "ssh", "stackoverflow"]
}, {
    "id": 'int',
        "hash": 'md5',
        "automessage": {},
        "interests": ["climbing", "football", "coffee"]
}];

// var exists = (myNumbers.indexOf(bar) > -1); //true

var largerCount = 0, index; // will contain the count & index of largest match
for (var i = 0; i < waiting_list.length; i++) { // iterate over the waiting list
    var current = waiting_list[i];
    var currentCount = 0; // get the current match count
    var incoming_array = incoming.interests; // get the incoming interest
    for (var j = 0; j < incoming_array.length; j++) {

        if(current.interests.indexOf(incoming_array[j]) > -1) { 
           currentCount++; // add to count if match is found
        }
        if(currentCount > largerCount) { // if current count is bigger then assign it to largerCounr
            largerCount = currentCount;
            index = i; // assign the index of match
        }
    }
    currentCount = 0;
}

if(index >= 0) {
console.log(waiting_list[index]); // print the match
} else {
    // add to waiting list
    waiting_list.push(incoming);
}

Upvotes: 1

georg
georg

Reputation: 215039

I'll answer the "find the closest element" part:

function intersection(a, b) {
    return a.filter(function(x) { return b.indexOf(x) >= 0 })
}

function closest(ary, arrays) {
    return arrays.map(function(x) {
        return [intersection(ary, x).length, x]
    }).sort(function(a, b) {
        return b[0] - a[0]
    })[0][1]
}

Example:

me = ["cars", "programming", "stackoverflow"]

interests = [
    ["cats", "animals", "cars"],
    ["programming", "ssh", "stackoverflow"],
    ["climbing", "football", "coffee"]
]

console.log(closest(me, interests))
> programming,ssh,stackoverflow

Upvotes: 2

Related Questions