You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

scorer.js 2.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. const config = require('../../../db/data-generator/config.json')
  2. const makeScoreLookup = (aspects, labels) => {
  3. const labelLookup = {}
  4. labels.forEach(label => (labelLookup[label.aspect_id] = label))
  5. const scoreLookup = {}
  6. aspects.forEach(aspect => {
  7. const key = labelLookup[aspect.aspect_id]
  8. scoreLookup[`${key.a}:${key.b}`] = {}
  9. Object.keys(aspect).forEach(aspect_id => {
  10. if (!labelLookup[aspect_id]) return
  11. const comp = labelLookup[aspect_id]
  12. const score = aspect[aspect_id]
  13. scoreLookup[`${key.a}:${key.b}`][`${comp.a}:${comp.b}`] = score
  14. })
  15. })
  16. return scoreLookup
  17. }
  18. const _isScorableResponse = res_key_id => {
  19. let isScorable = false
  20. if (config.resKeys.includes(res_key_id)) {
  21. isScorable = true
  22. }
  23. return isScorable
  24. }
  25. const scoreResponses = (seeker, potentialMatch, prescoreLookup) => {
  26. if (seeker.responses.length != potentialMatch.responses.length)
  27. return {
  28. error: `complete responses for profile: ${seeker.profile_id} unqeual to profile: ${potentialMatch.profile_id} | ${seeker.responses.length}:${potentialMatch.responses.length}`,
  29. }
  30. const aRes = seeker.responses.filter(res =>
  31. _isScorableResponse(res.response_key_id),
  32. )
  33. const bRes = potentialMatch.responses.filter(res =>
  34. _isScorableResponse(res.response_key_id),
  35. )
  36. const composite = []
  37. while (aRes.length + bRes.length > 0) {
  38. const mKey = resList => {
  39. let el = resList.shift()
  40. let pair = el.val
  41. el = resList.shift()
  42. return `${pair}:${el.val}`
  43. }
  44. composite.push(prescoreLookup[mKey(aRes)][mKey(bRes)])
  45. }
  46. const scoreAvg = composite.reduce((a, b) => a + b) / composite.length
  47. return {
  48. total: Math.round(scoreAvg),
  49. aspects: composite,
  50. }
  51. }
  52. const scoreAll = (profileList, userProfile, prescoreLookup) => {
  53. return profileList.map(profile => {
  54. return {
  55. // Uncomment to return the whole profile
  56. // ...profile,
  57. profile_id: profile.profile_id,
  58. score: scoreResponses(userProfile, profile, prescoreLookup),
  59. distance: profile.distance,
  60. }
  61. })
  62. }
  63. module.exports = {
  64. _isScorableResponse,
  65. scoreResponses,
  66. makeScoreLookup,
  67. scoreAll,
  68. }