Array reduce is not returning expected results - javascript
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!
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'))
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'))
Related
How to sort the data from the array in the order as they appear for the exact match?
I need to filter the data based on first matching character or string of that word and print the result as below. Input: 'T' or 'Th' or 'The' Output: ['The Shawshank Redemption', 'The Godfather', 'The Godfather: Part II', 'The Dark Knight', 'Dora the explorer'] Input: 'Da' Output:['Dark Knight', 'The Dark Knight'] In the first case, 'T/Th/The' is the exact match for ('The Shawshank Redemption', 'The Godfather', 'The Godfather: Part II', 'The Dark Knight'). Yes, Dora the explorer is also a valid one as 'T/Th/The' is part of the string, but I need to push it to the last. The logic what I wrote returns ["Dora the explorer", "The Shawshank Redemption", "The Godfather", "The Godfather: Part II", "The Dark Knight"] which is not correct. Same applies for the second one too. I'm not sure what did I do wrong here. const fruits = ['Dora the explorer', 'The Shawshank Redemption', 'The Godfather', 'The Godfather: Part II', 'The Dark Knight', 'Dark Knight']; const character = "The"; const filteredNames = fruits.filter((item) => { const subStrLength = character.length; return item.split(' ').some(el => el.slice(0, subStrLength).toLowerCase() === character.toLowerCase()) }).sort((a, b) => a.toLowerCase().indexOf(character) - b.toLowerCase().indexOf(character)) console.log(filteredNames)
Here's one approach. While sorting we check if both the movies to sort are starting with the character and store them in isGoodMatchA and isGoodMatchB, if one of them is false and the other true, then we give priority to the true one. Else if both of them are true or if both of them are false, we do a simple localeCompare to find which comes first. const fruits = ['Dora the explorer', 'The Shawshank Redemption', 'The Godfather', 'The Godfather: Part II', 'The Dark Knight', 'Dark Knight']; const character = "The"; const filteredNames = fruits .filter((item) => item.toLowerCase().includes(character.toLowerCase())) .sort((a, b) => { const key = character.toLowerCase(); const isGoodMatchA = a.toLowerCase().startsWith(key); const isGoodMatchB = b.toLowerCase().startsWith(key); if (isGoodMatchA ^ isGoodMatchB) { // XOR return isGoodMatchA ? -1 : 1; } return a.localeCompare(b); }); console.log(filteredNames) Array.prototype.includes() String.prototype.startsWith()
Why is my sorting algorithm not sorting correctly?
I was given this sorting function in the best answer to a question I posted. It worked on the example data, but does not appear to work on my actual data and I am not sure why. My data can be see here: JSON It's an object of objects like this: "Montana": { "superiors": [ "Massachusetts", "Oklahoma", "New Mexico" ], "inferiors": [ "North Carolina" ] } It exists to instruct the sorting function. Here, Montana must be higher up in the list than North Carolina. But below Massachusetts, Oklahoma, and New Mexico (nothing to do with geography by the way). Note to avoid confusion: This has nothing to do with the order of object keys. But the sorting isn't being followed precisely (it's mostly followed though). For example, states['North Carolina'].superiors.includes('Ohio') === true so why is 'Ohio' listed beneath 'North Carolina'? fetch('https://api.npoint.io/7571e85ef470a2a7f189') .then(data => data.json()) .then(states => { function mySort(arr) { const scores = Array(arr.length).fill(0); for (let i = 0; i < arr.length; i++) { for (let j = 0; j < arr.length; j++) { if (i === j) continue; const a = arr[i]; const b = arr[j]; if (states[a].inferiors.includes(b) || states[b].superiors.includes(a)) scores[j]++; else if (states[b].inferiors.includes(a) || states[a].superiors.includes(b)) scores[i]++; } } // Sort arr by scores: return arr.map((val, i) => [scores[i], val]) .sort((a, b) => a[0] - b[0]) .map(pair => pair[1]); } const names = Object.keys(states); console.log(mySort(names)); /* [ 'Tennessee', 'Oklahoma', 'Alaska', 'Wisconsin', 'Arkansas', 'New York', 'Nevada', 'Montana', 'Georgia', 'Massachusetts', 'Hawaii', 'Connecticut', 'California', 'Kansas', 'Utah', 'North Dakota', 'New Mexico', 'Nebraska', 'Pennsylvania', 'Louisiana', 'New Jersey', 'Arizona', 'Colorado', 'Maryland', 'Oregon', 'Missouri', 'Virginia', 'Rhode Island', 'Mississippi', 'South Carolina', 'Illinois', 'Texas', 'Florida', 'Washington', 'District of Columbia', 'Kentucky', 'Minnesota', 'Iowa', 'Alabama', 'New Hampshire', 'Idaho', 'South Dakota', 'Indiana', 'Michigan', 'North Carolina', 'Ohio' ] */ // states['North Carolina'].superiors.includes('Ohio') === true // so why is 'Ohio' listed beneath 'North Carolina'? }); Here is the JSON data in case the data in my link gets vandalized: {"Iowa":{"inferiors":[],"superiors":["Alaska","Oklahoma","California","Hawaii","New Jersey","Virginia","Florida","Washington","Minnesota","Texas","Idaho","Alabama","Ohio"]},"Ohio":{"inferiors":["North Carolina","Michigan","Iowa","New Hampshire"],"superiors":["New York","California","Arizona","Illinois","Texas","Pennsylvania","Florida","Indiana","Tennessee","Massachusetts","Washington","Colorado","District of Columbia","Maryland","Kentucky","Oregon","Oklahoma","Wisconsin","Nevada","New Mexico","Missouri","Virginia","Georgia","Nebraska","Minnesota","Louisiana","Hawaii","Alaska","New Jersey","Idaho","Alabama","Arkansas","Utah","Rhode Island","Mississippi","South Carolina","Connecticut","Montana","Kansas","North Dakota","South Dakota"]},"Utah":{"inferiors":["Idaho","South Dakota","Ohio","Michigan"],"superiors":["New York"]},"Idaho":{"inferiors":["Ohio","Iowa","South Dakota","Michigan","North Carolina"],"superiors":["Alaska","Oklahoma","California","Hawaii","Minnesota","New Jersey","Virginia","Florida","Washington","Texas","New York","Louisiana","Illinois","Arkansas","Utah","Rhode Island","Mississippi","Maryland","Nebraska","District of Columbia","Kentucky","Connecticut"]},"Texas":{"inferiors":["North Carolina","Michigan","Ohio","Indiana","Idaho","Alabama","Iowa"],"superiors":["New York","California","Tennessee","Massachusetts","Oklahoma","Wisconsin","Nevada","New Mexico","Alaska","Hawaii"]},"Alaska":{"inferiors":["California","Hawaii","New Jersey","Virginia","Florida","Washington","Minnesota","Texas","Idaho","Alabama","Ohio","Iowa","New Mexico","Mississippi","Rhode Island","North Dakota","South Carolina","District of Columbia","Colorado","Arizona","Kentucky","New Hampshire","Oregon","Nebraska","Illinois","Indiana","South Dakota","North Carolina"],"superiors":["Tennessee"]},"Hawaii":{"inferiors":["Minnesota","Kentucky","Washington","Pennsylvania","Illinois","Georgia","Maryland","Ohio","New Jersey","Virginia","Florida","Texas","Idaho","Alabama","Iowa","Mississippi","Rhode Island","North Dakota","South Carolina","District of Columbia","Colorado","Arizona","New Hampshire","Missouri","Utah","Louisiana","Michigan"],"superiors":["New York","Tennessee","Oklahoma","Alaska","Nevada"]},"Kansas":{"inferiors":["Indiana","North Carolina"],"superiors":["Wisconsin","New York","California"]},"Nevada":{"inferiors":["California","New Mexico","Illinois","Texas","Missouri","Virginia","District of Columbia","Ohio","North Carolina","Michigan","Maryland","Colorado","Arizona","Oregon","Indiana","Kentucky","Louisiana","Florida","Hawaii","Massachusetts","South Carolina","Mississippi","Minnesota","North Dakota","New Hampshire","Rhode Island","Washington","Utah","New Jersey","Nebraska","Alabama","South Dakota"],"superiors":["Tennessee","Oklahoma","Wisconsin"]},"Oregon":{"inferiors":["Ohio","Indiana","North Carolina","Michigan","Alabama","South Dakota"],"superiors":["New York","Tennessee","Massachusetts","Oklahoma","Wisconsin","California","Nevada","Alaska"]},"Alabama":{"inferiors":["Ohio","Iowa","North Carolina"],"superiors":["Tennessee","Nevada","Alaska","Nebraska","New Mexico","New Jersey","Kentucky","Oregon","Rhode Island","Illinois"]},"Arizona":{"inferiors":["Indiana","Ohio","North Carolina","Michigan","New Hampshire"],"superiors":["California","New York","Tennessee","Massachusetts","Wisconsin","Nevada","New Mexico","Alaska","Hawaii"]},"Florida":{"inferiors":["Indiana","Ohio","North Carolina","Michigan","Iowa","Idaho","South Dakota"],"superiors":["Tennessee","New York","Massachusetts","Wisconsin","California","New Mexico","Oklahoma","Nevada","Alaska","Hawaii"]},"Georgia":{"inferiors":["Ohio"],"superiors":["Tennessee","New York","Oklahoma"]},"Indiana":{"inferiors":["Ohio","North Carolina","Michigan","South Dakota"],"superiors":["New York","California","Arizona","Illinois","Texas","Pennsylvania","Florida","Oklahoma","Tennessee","Wisconsin","Oregon","District of Columbia","Maryland","Virginia","Washington","Missouri","Nebraska","Colorado","Kansas","Kentucky","Nevada","Louisiana","New Mexico","Minnesota","Rhode Island","Connecticut","Mississippi","Alaska","New Jersey"]},"Montana":{"inferiors":["North Carolina"],"superiors":["Massachusetts","Oklahoma","New Mexico"]},"Arkansas":{"inferiors":["South Dakota","Ohio","Michigan"],"superiors":["New York","California"]},"Colorado":{"inferiors":["Ohio","Michigan","North Carolina"],"superiors":["New York","Tennessee","Massachusetts","Wisconsin","California","Nevada"]},"Illinois":{"inferiors":["Indiana","Ohio","Michigan","South Dakota","Alabama","North Carolina"],"superiors":["New York","California","Tennessee","Massachusetts","Oklahoma","Wisconsin","Nevada","New Mexico","Hawaii"]},"Kentucky":{"inferiors":["Ohio","Indiana","Michigan","North Carolina","Idaho","South Dakota","New Hampshire"],"superiors":["New York","Tennessee","Massachusetts","Wisconsin","Nevada","California","Oklahoma","Hawaii","New Mexico","Alaska"]},"Maryland":{"inferiors":["Ohio","North Carolina","Michigan","Indiana","Idaho","South Dakota"],"superiors":["New York","Tennessee","Massachusetts","Oklahoma","California","Wisconsin","Nevada","New Mexico"]},"Michigan":{"inferiors":[],"superiors":["Florida","New York","California","Illinois","Texas","Pennsylvania","Arizona","Tennessee","Oklahoma","Wisconsin","Nevada","New Mexico","District of Columbia","Missouri","Virginia","North Carolina","Ohio","Washington","Georgia","Maryland","Nebraska","Colorado","Indiana","Oregon","Louisiana","Kentucky","Massachusetts","Hawaii","Rhode Island","Mississippi","Utah"]},"Missouri":{"inferiors":["Ohio","North Carolina","Michigan","Indiana"],"superiors":["Tennessee","Oklahoma","Wisconsin","California","Nevada","New Mexico","New York","Massachusetts","Hawaii"]},"Nebraska":{"inferiors":["Ohio","North Carolina","Michigan","Indiana","Idaho","South Dakota","Alabama"],"superiors":["New York","Tennessee","California","New Mexico","Oklahoma","Nevada","Alaska"]},"New York":{"inferiors":["California","Illinois","Texas","Pennsylvania","Arizona","Florida","Indiana","Ohio","North Carolina","Michigan","Washington","Colorado","District of Columbia","Maryland","Kentucky","Oregon","Massachusetts","New Mexico","Minnesota","Missouri","Nebraska","Virginia","Kansas","Louisiana","Georgia","Hawaii","Arkansas","Utah","Rhode Island","Mississippi","Idaho","South Dakota","South Carolina","New Jersey","Connecticut","New Hampshire"],"superiors":["Wisconsin","Tennessee","Oklahoma"]},"Oklahoma":{"inferiors":["Nevada","California","New Mexico","Illinois","Texas","Missouri","Virginia","District of Columbia","Ohio","North Carolina","Michigan","Wisconsin","Oregon","Maryland","Washington","Indiana","New York","Hawaii","Minnesota","Kentucky","Pennsylvania","Georgia","Florida","Louisiana","Idaho","South Dakota","Nebraska","Rhode Island","Connecticut","Mississippi","South Carolina","New Jersey","New Hampshire","Montana","Kansas"],"superiors":["Tennessee"]},"Virginia":{"inferiors":["Ohio","North Carolina","Michigan","Indiana","Iowa","Idaho","South Dakota"],"superiors":["Tennessee","Oklahoma","Wisconsin","California","Nevada","New Mexico","New York","Alaska","Hawaii"]},"Louisiana":{"inferiors":["Indiana","Ohio","Michigan","Idaho","South Dakota"],"superiors":["Nevada","New York","California","Tennessee","New Mexico","Oklahoma"]},"Minnesota":{"inferiors":["Ohio","North Carolina","Idaho","Alabama","Iowa","South Dakota","Michigan","Indiana","New Hampshire"],"superiors":["Wisconsin","New York","California","Massachusetts","New Mexico","Tennessee","Oklahoma","Hawaii","Alaska","Nevada"]},"Tennessee":{"inferiors":["Illinois","Washington","Florida","Colorado","District of Columbia","Texas","Maryland","Kentucky","Oregon","Arizona","Ohio","Oklahoma","Wisconsin","Nevada","California","New Mexico","Missouri","Virginia","North Carolina","Michigan","Georgia","Nebraska","Indiana","Pennsylvania","New York","Hawaii","Minnesota","Louisiana","Rhode Island","Mississippi","Utah","Alaska","New Jersey","Alabama","South Dakota"],"superiors":[]},"Wisconsin":{"inferiors":["Nevada","California","New Mexico","Illinois","Texas","Missouri","Virginia","District of Columbia","Ohio","North Carolina","Michigan","Oregon","Maryland","Washington","Indiana","Massachusetts","Pennsylvania","Florida","Minnesota","New York","Kansas","Arizona","Kentucky","Colorado"],"superiors":["Oklahoma","Tennessee"]},"California":{"inferiors":["Illinois","Texas","Pennsylvania","Arizona","Florida","Indiana","Ohio","North Carolina","Michigan","Missouri","Virginia","District of Columbia","Oregon","Maryland","Washington","Massachusetts","New Mexico","Minnesota","Nebraska","Colorado","Kansas","Kentucky","Louisiana","New Jersey","Idaho","Alabama","Iowa","Arkansas","Utah","Rhode Island","Mississippi","South Dakota","South Carolina","Connecticut","New Hampshire"],"superiors":["New York","Tennessee","Oklahoma","Wisconsin","Nevada","Alaska"]},"New Jersey":{"inferiors":["Iowa"],"superiors":["Alaska","Oklahoma","California","Hawaii","New York","New Mexico","Tennessee","Nevada"]},"New Mexico":{"inferiors":["Illinois","Texas","Missouri","Virginia","District of Columbia","Ohio","North Carolina","Michigan","Pennsylvania","Florida","Minnesota","Indiana","Kentucky","Louisiana","Arizona","Washington","Nebraska","Maryland","South Carolina","New Jersey","Rhode Island","Connecticut","New Hampshire","Mississippi","North Dakota","Colorado","Montana","Kansas","Oregon","Alabama","South Dakota"],"superiors":["Wisconsin","Tennessee","Oklahoma","New York","California","Nevada","Alaska"]},"Washington":{"inferiors":["Ohio","North Carolina","Michigan","Indiana","Iowa"],"superiors":["Tennessee","New York","Massachusetts","California","Oklahoma","Wisconsin","New Mexico","Hawaii","Alaska","Nevada"]},"Connecticut":{"inferiors":["Idaho","Indiana","South Dakota","North Carolina","Ohio","New Hampshire"],"superiors":["New York","Oklahoma","New Mexico","Massachusetts"]},"Mississippi":{"inferiors":["Idaho","South Dakota","Ohio","Michigan","Indiana","North Carolina","New Hampshire"],"superiors":["Alaska","Tennessee","Hawaii","New Mexico","Nevada","Massachusetts"]},"North Dakota":{"inferiors":["Ohio","New Hampshire"],"superiors":["Alaska","Tennessee","Hawaii","New Mexico","Nevada","Massachusetts"]},"Pennsylvania":{"inferiors":["North Carolina","Michigan","Indiana","Ohio","New Hampshire"],"superiors":["New York","California","Wisconsin","New Mexico","Massachusetts","Tennessee","Oklahoma","Hawaii"]},"Rhode Island":{"inferiors":["Idaho","South Dakota","Ohio","Michigan","Indiana","North Carolina","New Hampshire","Alabama"],"superiors":["New York","Oklahoma","New Mexico","California","Alaska","Tennessee","Hawaii","Nevada","Massachusetts"]},"South Dakota":{"inferiors":["Ohio","North Carolina"],"superiors":["New York","California","Illinois","Arkansas","Louisiana","Minnesota","Utah","Rhode Island","Florida","Mississippi","Maryland","Idaho","Oklahoma","Nebraska","District of Columbia","Kentucky","Connecticut","Virginia","Indiana"]},"Massachusetts":{"inferiors":["Illinois","Washington","Florida","Colorado","District of Columbia","Texas","Maryland","Kentucky","Oregon","Arizona","Ohio","Pennsylvania","Minnesota","Indiana","North Carolina","Montana","Connecticut","Rhode Island","Kansas","South Carolina","Mississippi","North Dakota","New Hampshire","Missouri","Utah","Louisiana","Michigan"],"superiors":["Wisconsin","New York","California","Nevada","Tennessee"]},"New Hampshire":{"inferiors":[],"superiors":["Oklahoma","New York","New Mexico","California","Pennsylvania","Maryland","South Carolina","Virginia","New Jersey","Rhode Island","Connecticut","Alaska","Nevada","Hawaii","Massachusetts","Mississippi","Minnesota","Arizona","North Dakota","Kentucky","Ohio"]},"North Carolina":{"inferiors":["Michigan"],"superiors":["New York","California","Texas","Illinois","Pennsylvania","Arizona","Florida","Indiana","Ohio","Wisconsin","Tennessee","Oklahoma","New Mexico","Nevada","Washington","Georgia","District of Columbia","Missouri","Maryland","Nebraska","Massachusetts","Minnesota","Colorado","Oregon","Virginia","Kentucky","Rhode Island","Connecticut","Mississippi","Idaho","Montana","Kansas","Alaska","New Jersey","Alabama","South Dakota"]},"South Carolina":{"inferiors":["New Hampshire"],"superiors":["Oklahoma","New York","New Mexico","California","Alaska","Tennessee","Hawaii","Nevada","Massachusetts"]},"District of Columbia":{"inferiors":["Ohio","North Carolina","Michigan","Indiana","Idaho","South Dakota"],"superiors":["New York","Tennessee","Massachusetts","Wisconsin","Oklahoma","California","Nevada","New Mexico","Alaska","Hawaii"]}}
You have a partial order only not a total order (not all states list all others in their superiors/inferiors list), so your score calculation doesn't work. States end up with a score depending on how often they were mentioned, not what their relative order is. You'll need to implement a topological sort algorithm.
Your data doesn't contain contradictions, but it certainly doesn't list everything correctly. Example: Iowa-Oklahoma pair. Oklahoma is listed as being superior to Iowa, but Iowa is not listed as being inferior to Oklahoma.
Filter array by testing against all other items using ramda
I have an array of people that I would like to filter against itself (to test against all other items in the array): const people = [{ name: "James Cromwell", region: "Australia" }, { name: "Janet April", region: "Australia" }, { name: "David Smith", region: "USA" }, { name: "Tracey Partridge", region: "USA" }] What I would like to do in this case is to be left with any people whose: namestarts with the same letter region value is the same In this case the result would be: [{ name: "James Cromwell", region: "Australia" }, { name: "Janet April", region: "Australia" }] I’ve looked at doing a combination of filter and any but with no joy. My decision to use ramda here is that I’m using this in an existing ramda compose function to transform the data.
Group the elements by a key generated from the region and the 1st letter of the name. Reject any group with length 1, and then convert back to array with R.value, and flatten. Note: this solution will return multiple groups of "identical" people. If you want only one group, you can take the 1st one, or the largest one, etc... instead of getting the values and flattening. const { compose, groupBy, reject, propEq, values, flatten } = R const fn = compose( flatten, // flatten the array - or R.head to get just the 1st group values, // convert to an array of arrays reject(propEq('length', 1)), // remove groups with 1 items groupBy(({ name: [l], region }) => `${region}-${l.toLowerCase()}`) // collect into groups by the requested key ) const people = [{"name":"James Cromwell","region":"Australia"},{"name":"Janet April","region":"Australia"},{"name":"David Smith","region":"USA"},{"name":"Tracey Partridge","region":"USA"}] const result = fn(people) console.log(result) <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
const people = [{ name: "James Cromwell", region: "Australia" }, { name: "Janet April", region: "Australia" }, { name: "David Smith", region: "USA" }, { name: "Tracey Partridge", region: "USA" }]; let output = people .filter((p1, i1) => people.some((p2, i2) => i1 !== i2 && p1.region === p2.region && p1.name[0] === p2.name[0])); console.log(output);
Inserting variables into regular expressions
I'm trying to write code that will allow user to check to see if I have been to a specific country. I've tried this by getting input from user via prompt. Taking that input, storing it into a variable and then inserting that variable into a regex. From there, I attempted to use the .some method on my array of countries, utilizing the regex and the user input variable to determine whether or not I have been to the country that the user specifies. var countries = ['US', 'UK', 'Canda', 'Mexico', 'Panama', 'Dominican Republic', 'Brazil', 'Germany', 'France', 'Portugal', 'Spain', 'the Netherlands']; var userCountry = prompt("Please enter a country", ""); var beenToUserCountry = countries.some(country => /^userCountry$/i.test(country)); if (beenToUserCountry) { document.write(`Yes, I have been to ${userCountry}.`); } else { document.write(`No, I haven't been to ${userCountry} yet.`); } I expect that the code will print "Yes..." for countries that a part of my countries array and and "No..." for ones that are not. Instead, each country that I insert into the prompt gets me a "No..." Help!
You can use a RegExp object for that, here is an example: var countries = ['US', 'UK', 'Canda', 'Mexico', 'Panama', 'Dominican Republic', 'Brazil', 'Germany', 'France', 'Portugal', 'Spain', 'the Netherlands']; var userCountry = prompt("Please enter a country", ""); var beenToUserCountry = countries.some(country => new RegExp(`^${userCountry}$`, "i").test(country)); if (beenToUserCountry) { document.write(`Yes, I have been to ${userCountry}.`); } else { document.write(`No, I haven't been to ${userCountry} yet.`); } As #Bergi has mentioned, you should probably escape userCountry to remove any special characters from it, you can find a good example of how you can do that here
Why is typeahead matching periods?
I am using the same code from the typeahead example here. However if you type in a period . the dropdown will appear with matches. Is all this code above the array definition necessary? Is there an easier way to accomplish the same thing where you won't get matches for periods if there are no periods in your array? I see the bloodhound example below it accomplishes the same thing and doesn't match periods but is it using var states to define an array and then using var states to construct a new bloodhound engine is this a mistake? Copied code from the website: var substringMatcher = function(strs) { return function findMatches(q, cb) { var matches, substringRegex; // an array that will be populated with substring matches matches = []; // regex used to determine if a string contains the substring `q` substrRegex = new RegExp(q, 'i'); // iterate through the pool of strings and for any string that // contains the substring `q`, add it to the `matches` array $.each(strs, function(i, str) { if (substrRegex.test(str)) { matches.push(str); } }); cb(matches); }; }; var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming' ]; $('#the-basics .typeahead').typeahead({ hint: true, highlight: true, minLength: 1 }, { name: 'states', source: substringMatcher(states) }); In my case I am generating an array of tags so instead of the states I am using var tags = <%= raw Tag.all.pluck(:name) %>;
You may find indexOf to be more useful than a regex for your application. if (haystack.indexOf(needle) != -1) { /* needle is in haystack */ } or, case insensitively: if (haystack.toLowerCase().indexOf(needle.toLowerCase()) != -1) { } something like this: function findMatches(q, cb) { var lq = q.toLowerCase(); var matches = []; $.each(strs, function(i, str) { if (str.toLowerCase().indexOf(lq) != -1) matches.push(str); }); cb(matches); }
So regular expressions are "complicated", and easy to get wrong. "." for instance has special meaning in regex which matches any charachter except newline in JS, so for example based on Mozilla's docs RexExp(".n", "i") would match ".n", "an", "in", "?n" and many more. Regular expressions are difficult to get right. #John-Hascall's suggestion is a good fix for the problem.