Reputation: 3355
I'm working on a search function that is getting passed through an array filter, followed by a reduce to match the correct strings to each other but I'm experiencing some difficulties getting the expected results.
I have an enum of common phrases that I want to map to their values, for instance if Amer
is searched it should also match American
. To achieve this I've setup an object with some values with a reduce that should add the value to the search string, for instance if either the API data or the search data contains U Street African Amer
it should turn it into u street african amer american
in the return. If it doesn't find any mapped data it should pass back the original function arguement.
const acronymEnum = {
MT: 'Mountain',
AMER: 'American',
PL: 'Place',
UDC: 'Univeristy of the District of Columbia',
AU: 'American University',
AVE: 'Avenue',
CUA: 'Catholic University of America',
NOMA: 'North of Massechusets Avenue',
GMU: 'George Mason University',
VT: 'Virginia Tech',
UVA: 'University of Virginia',
RAEGAN: 'DCA',
ST: 'Street',
SW: 'South West',
SQ: 'Square',
PENN: 'Pennsylvania',
};
function convertStationAcronym(stationName) {
return Object.keys(acronymEnum).reduce((previous, current) => {
if (stationName.toLowerCase().includes(current.toLowerCase())) {
console.log('trigger the match', current)
return stationName.concat(` ${acronymEnum[current]}`).toLowerCase();
} else {
return previous.toLowerCase();
}
}, '');
}
console.log(convertStationAcronym('U Street African Amer'))
The issue I'm running into is that it's returning either undefined, or it's adding only one mapped phrase to the return depending on what is passed into the function. Any help would be appreciated!
Upvotes: 0
Views: 123
Reputation: 664336
You will want to start the reduce
with stationName
as the initial value, and then always concatenate to previous
not the original stationName
value:
const acronymEnum = {
MT: 'Mountain',
AMER: 'American',
PL: 'Place',
UDC: 'Univeristy of the District of Columbia',
AU: 'American University',
AVE: 'Avenue',
CUA: 'Catholic University of America',
NOMA: 'North of Massechusets Avenue',
GMU: 'George Mason University',
VT: 'Virginia Tech',
UVA: 'University of Virginia',
RAEGAN: 'DCA',
ST: 'Street',
SW: 'South West',
SQ: 'Square',
PENN: 'Pennsylvania',
};
function convertStationAcronym(stationName) {
return Object.keys(acronymEnum).reduce((previous, currentKey) => {
const re = new RegExp("\\b" + currentKey + "\\b", "i"); // TODO: escape special characters
if (re.test(stationName)) {
console.log('trigger the match', currentKey)
return previous.concat(' ', acronymEnum[currentKey]);
// ^^^^^^^^
} else {
return previous;
}
}, stationName).toLowerCase();
// ^^^^^^^^^^^
}
console.log(convertStationAcronym('U Street African Amer'))
Upvotes: 2
Reputation: 3426
The alternative solution to the problem can be dividing the input string into an array and for each element in the array, we will find the entry in acronymEnum Object. This approach will be more efficient if the length of the input string is less.
const acronymEnum = {
MT: 'Mountain',
AMER: 'American',
PL: 'Place',
UDC: 'Univeristy of the District of Columbia',
AU: 'American University',
AVE: 'Avenue',
CUA: 'Catholic University of America',
NOMA: 'North of Massechusets Avenue',
GMU: 'George Mason University',
VT: 'Virginia Tech',
UVA: 'University of Virginia',
RAEGAN: 'DCA',
ST: 'Street',
SW: 'South West',
SQ: 'Square',
PENN: 'Pennsylvania',
};
function convertStationAcronym(stationName) {
let stationNameArray = stationName.split(" ");
let result = stationNameArray.map((item)=> {
return acronymEnum[item.toUpperCase()]
? acronymEnum[item.toUpperCase()]
:item
})
return result.join(" ");
}
console.log(convertStationAcronym('U Street African Amer'))
Upvotes: 1