let data = [
{
'name': 'John Doe',
'sex': 'male',
'pos': [ 43.036871, -89.324967 ],
'tags': [ 'general', 'basic' ]
},
{
'name': 'Amy Schmidt',
'sex': 'female',
'pos': [ 39.48586, -121.387316 ],
'tags': [ 'honest', 'uneven' ]
},
{
'name': 'Robert Summers',
'sex': 'male',
'pos': [ 33.657366, -86.643871 ],
'tags': [ 'efficient', 'psychotic' ]
},
{
'name': 'Steven Walls',
'sex': 'male',
'pos': [ 43.484856, -83.849829 ],
'tags': [ 'huge', 'grumpy' ]
},
{
'name': 'Elizabeth Bateman',
'sex': 'female',
'pos': [ 38.886231, -99.306865 ],
'tags': [ 'heavy', 'goofy' ]
},
{
'name': 'Robert Galusha',
'sex': 'male',
'pos': [ 29.713645, -95.534338 ],
'tags': [ 'vast', 'depressed' ]
}
];
function search(person, tags) {
let scores = { }, distances = { },
lat = person.pos[0], lng = person.pos[1];
data.filter(user => user.name !== person.name).forEach(user => {
scores[user.name] = 0;
scores[user.name] += user.tags.filter(tag => tags.indexOf(tag) > -1).length;
scores[user.name] += user.sex !== person.sex ? 1 : 0;
let dlat = Math.abs(lat - user.pos[0]), dlng = Math.abs(lng - user.pos[1]),
distance = Math.sqrt(Math.pow(dlat, 2) + Math.pow(dlng, 2));
distances[user.name] = distance;
});
// Needed to normalize the distances
let maxDistance = Object.values(distances).sort((a, b) => b - a).shift();
for(let name in distances)
// Substract the normalized distance from 1, so: shorter distance = more points
scores[name] += (1 - distances[name] / maxDistance);
// Sort by score; the best match is the first element
return Object.entries(scores).sort((a, b) => b[1] - a[1]);
}
console.log(search(data[0], [ 'honest', 'vast' ]))