generate-words-freqmap
Version:
Generate frequency map from array of strings.
78 lines (67 loc) • 2.76 kB
text/typescript
import CustomError from 'fullfiller-common/src/CustomError';
import { notEnoughWordsInFreqMap } from 'fullfiller-common/src/errorMessages';
import { freqMapType } from 'fullfiller-common/src/types';
import emphasize from './emphasize';
import generateFreqMapWeightAsKey from './generateFreqMapWeightAsKey';
import generateFreqMapWordAsKey from './generateFreqMapWordAsKey';
import getFreqMapWordsQuantity from './getFreqMapWordsQuantity';
import shortenFreqMap from './shortenFreqMap';
/**
* @property emphasizeBy `wordsToEmphasize` will have their weight multiplied by this number.
* @property wordsQuantityMin Return should have at least this quantity of words, otherwise error.
* @property tierWeightMin Filter out from return any tier which weight is less than this number.
* @property tierWeightMax Filter out from return any tier which weight is more than this number.
* @property mergePosteriorTiersAt Merge at this tier all posterior tiers (tiers w/ higher weight).
* @property caseInsensitive If `true`, all words will be converted to lowercase.
*/
type optionsType = {
emphasizeBy: number;
wordsQuantityMin: number;
tierWeightMin: number;
tierWeightMax: number;
mergePosteriorTiersAt: number;
caseInsensitive: boolean;
};
const optionsDefault: optionsType = {
emphasizeBy: 2, // double weight for any word in `wordsToEmphasize`
wordsQuantityMin: 0, // don't throw error even if freqMap doesn't contain any word
tierWeightMin: 1, // don't filter out any tier
tierWeightMax: -1, // disable option
mergePosteriorTiersAt: -1, // disable option
caseInsensitive: false,
};
/**
* Generate `freqMap` from `wordsArray`.
* @param wordsArray
* @param wordsToEmphasize Subset of `wordsArray` to emphasize.
* @param optionsArg Miscellaneous options.
* @throws Error if `freqMap` has less words than required by `options.wordsQuantityMin`.
* @returns freqMap.
*/
function generateFreqMap(
wordsArray: string[],
wordsToEmphasize?: string[],
optionsArg?: Partial<optionsType>
): freqMapType {
const options = { ...optionsDefault, ...optionsArg };
const freqMapWordAsKey = emphasize(
generateFreqMapWordAsKey(wordsArray, options.caseInsensitive),
wordsToEmphasize || [],
options.emphasizeBy
);
const freqMap = shortenFreqMap(
generateFreqMapWeightAsKey(freqMapWordAsKey),
options.tierWeightMin,
options.tierWeightMax,
options.mergePosteriorTiersAt
);
const freqMapWordsQuantity = getFreqMapWordsQuantity(freqMap);
if (freqMapWordsQuantity < options.wordsQuantityMin) {
throw new CustomError(
notEnoughWordsInFreqMap(options.wordsQuantityMin, freqMapWordsQuantity),
'generate-words-freqmap'
);
}
return freqMap;
}
export default generateFreqMap;