1
1

ContentGroup.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. enum ContentGroupMatch {
  2. NO_MATCH,
  3. PARTIAL_MATCH,
  4. PERFECT_MATCH
  5. }
  6. interface ContentGroupMatchResult {
  7. type : ContentGroupMatch;
  8. unmatched : Array<ContentUnit>;
  9. }
  10. class ContentGroup {
  11. private units : Array<ContentUnit> = [];
  12. private matching : Array<ContentUnit>;
  13. constructor (...units : Array<ContentUnit>) {
  14. units.forEach(unit => {
  15. this.addUnit(unit);
  16. })
  17. }
  18. public addUnit (unit : ContentUnit) {
  19. this.units.push(unit);
  20. return this;
  21. }
  22. public reset () {
  23. this.matching = this.units.slice();
  24. }
  25. public isMatching () {
  26. return this.matching.length;
  27. }
  28. public setMatching (matching : Array<ContentUnit>) {
  29. this.matching = matching;
  30. }
  31. public isMatch (cg : ContentGroup) : ContentGroupMatchResult {
  32. let unmatched = cg.matching.slice();
  33. let matching = this.units.slice();
  34. for (let i = matching.length - 1; i >= 0; i--) {
  35. for (let k = unmatched.length - 1; k >= 0; k--) {
  36. if (matching[i].isMatch(unmatched[k])) {
  37. unmatched.splice(k, 1);
  38. matching.splice(i, 1);
  39. break;
  40. }
  41. }
  42. }
  43. return {
  44. type : matching.length > 0 ? ContentGroupMatch.NO_MATCH :
  45. unmatched.length == 0 ? ContentGroupMatch.PERFECT_MATCH :
  46. ContentGroupMatch.PARTIAL_MATCH,
  47. unmatched : unmatched
  48. }
  49. }
  50. public getScore () {
  51. let score = 0;
  52. this.units.forEach(unit => {
  53. score += unit.getScore();
  54. });
  55. return Math.floor((score / this.units.length) * 10) + this.units.length; // If we keep precision too high, random won't work.
  56. }
  57. public matchAgainst (a : Array<ContentGroup>) : Array<number> {
  58. let matches = [];
  59. this.reset();
  60. for (let i = 0; i < a.length; i++) {
  61. let match = a[i].isMatch(this);
  62. if (match.type != ContentGroupMatch.NO_MATCH) {
  63. matches.push(i);
  64. this.setMatching(match.unmatched);
  65. }
  66. if (!this.isMatching()) {
  67. return matches;
  68. }
  69. }
  70. return undefined;
  71. }
  72. }