Spaces:
Runtime error
Runtime error
| /** | |
| * Copyright (C) 2021 Thomas Weber | |
| * | |
| * This program is free software: you can redistribute it and/or modify | |
| * it under the terms of the GNU General Public License version 3 as | |
| * published by the Free Software Foundation. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
| */ | |
| const normalize = text => text | |
| .normalize('NFD') | |
| .replace(/[\u0300-\u036f]/g, '') | |
| .toLowerCase() | |
| .replace(/['"()\-+,./[\]]/g, ' ') | |
| .trim(); | |
| const splitToWords = text => normalize(text) | |
| .split(' ') | |
| .filter(i => i); | |
| const parseTexts = texts => { | |
| const result = []; | |
| for (const {score, text} of texts) { | |
| result.push({ | |
| score, | |
| words: splitToWords(text) | |
| }); | |
| } | |
| return result; | |
| }; | |
| class Search { | |
| constructor (texts) { | |
| this.items = texts.map(parseTexts); | |
| } | |
| search (query) { | |
| const terms = splitToWords(query); | |
| const result = []; | |
| const processItem = item => { | |
| let totalScore = 0; | |
| for (const term of terms) { | |
| let highestScoreForTerm = 0; | |
| for (const group of item) { | |
| for (const word of group.words) { | |
| const wordIndex = word.indexOf(term); | |
| if (wordIndex !== -1) { | |
| let multiplier; | |
| if (wordIndex === 0) { | |
| multiplier = 1.5; | |
| } else { | |
| multiplier = 1; | |
| } | |
| const itemScore = group.score * multiplier; | |
| if (itemScore > highestScoreForTerm) { | |
| highestScoreForTerm = itemScore; | |
| } | |
| } | |
| } | |
| } | |
| if (highestScoreForTerm === 0) { | |
| return; | |
| } | |
| totalScore += highestScoreForTerm; | |
| } | |
| return totalScore; | |
| }; | |
| for (let i = 0; i < this.items.length; i++) { | |
| const score = processItem(this.items[i]); | |
| if (score > 0) { | |
| result.push({ | |
| index: i, | |
| score | |
| }); | |
| } | |
| } | |
| result.sort((a, b) => b.score - a.score); | |
| return result; | |
| } | |
| } | |
| export default Search; | |