Regex using array.filter in javascript - javascript

I'm trying to use a regular expression to filter the name column in a csv file that has be put into an object array. Everything works fine if I type the exact value.
values I want "king" to match are below:
kingkong, king kong, king-kong, king_kong, king11, kongking, kong-king, kong_king, kong king, 11king
I've tried using filter and find methods but I want to use filter to return multiple values if they exist. I have tried the following regex but can't figure out the proper sytax if it is even correct.
const CSVToJSON = require('csvtojson');
const user = "king";
CSVToJSON().fromFile("./locations.csv").then(source => {
var found = source.filter(function(v, i){
return ((v["name"]== /\bking.*/g));
})

You can use the following approach.
const CSVToJSON = require('csvtojson');
CSVToJSON().fromFile("./locations.csv").then(source => {
var found = source.filter(function(v, i){
return ((v["name"].match(/king/g)));
});

return statement could be something like
return ((/king/g).test(v["name"]));
OR
return ((v["name"].match(/king/g)));
Both should work

However, your sample patterns show that king might stand either at the beginning or at the end of the target (bot can't have both prefix and suffix). If I am right, that means you don't need regex for that.
const CSVToJSON = require('csvtojson');
const user = "king";
CSVToJSON().fromFile("./locations.csv").then(source => {
var found = source.filter((v, i) => v.startsWith(user) || v.endsWith(user))
/*rest of the code */
});
If king can stand anywhere, you can simply use includes instead.

This is what worked, I'm totally new to JavaScript:
const user = args;
var regex = new RegExp(user, "g");
CSVToJSON().fromFile("./locations.csv").then(source => {
var found = source.filter(function(v, i){
return ((v["name"].match(regex)));
})

Related

JS React: replacing regex with component in a string

Given a string with the format:
'This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.'
I'd like to split it using a RegEx and replace the coincidences with some React components. The string would have the type of component (FaIcon) and a props in it such as the name of the icon (Upload).
The objective with this is to be able to use React components within translated strings, and the expected return value would be something like:
[
'This is a string with some ',
<FaIcon iconName="Upload" />,
' in it as ',
<FaIcon iconName="Download" />,
' these two.'
]
The method
Currently, I've got a method which returns either a string or an array. This is compatible with React render methods, since if we return an array it will be capable of rendering any components on that array.
As I'll use it to translate some strings, I've created this custom hook:
const useCustomTranslation = () => {
const { t } = useTranslation();
const tlt = (...args) => {
// const str = t(...args);
const testStr =
'This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.';
const reg = /(?<=::FaIcon)(.*?)(?=::)/g;
const preStrAr = testStr.split(reg);
console.log(preStrAr);
};
return { tlt };
};
The problem
Currently, this method is logging this:
[
"This is a string with some ::FaIcon",
"Upload",
":: icons in it as ::FaIcon",
"Download",
":: these two."
]
As you can see, it's not including the ::FaIcon and the final ::, as I haven't been able to find the right Regex to do so. But even if I got to that point, I feel like then I should have to re-iterate through the array to replace the strings with the right component, again using Regex to see if the array item matches the right format.
I find this somehow overcomplicated, and I think there has to be a much cleaner and easy way to get it (correct me if maybe I'm wrong and this is the only way).
Is there any way where I can split a string using a Regex, using part of the matched group to replace the string by another content using that matched string?
Perhaps you meant to do this?
/::FaIcon(.*?)::/ without the look
const str = `This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.`
const newText = str.replace(/::FaIcon(.*?)::/g,function(_,match) {
return `<FaIcon iconName="${match}" />`
})
console.log(newText)
To make an array you can do
const str = `This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.`
const newText = str.replace(/\s?::FaIcon(.*?)::\s?/g,function(_,match) {
return `::<FaIcon iconName="${match}" />::`
}).split("::")
console.log(newText)
Finally, I've made it using (sadly) the re-iteration method, as it's the only way I can see it would work. Thanks to #mplungjan for his first answer, which gave me the hints to get it working:
export const replaceIconInStr = (str) => {
// Matches the whole icon component pattern
const regComponent = /(::FaIcon.*?::)/g;
// Matches just the component prop we need
const regIconName = /::FaIcon(.*?)::/g;
// Split the string by the component pattern
const splittedStr = str.split(regComponent);
// If there are any matches
if (splittedStr.length) {
// Match the elements in the array and get the prop to replace it by the real component
return splittedStr.map((el) => {
const matched = regIconName.exec(el)?.[1];
if (matched) {
return <FaIcon iconName={matched} />;
}
return el;
});
}
// If there is no pattern matching, return the original string
return str;
};

Remove a URL search parameter when there is duplicate names?

I am trying to manipulate my URL using URLSearchParams. However URLSearchParams.delete() expects the name of the param. If I have params with the same name, (from what I've tested in chrome) It will delete all params with that name. Is there a way to delete by both name and value?
My query looks something like this:
?color[]=Black&color[]=Green&material[]=Steel
So when I call .delete("color[]") it will remove both color[]= params, but what if I want to only remove a specific one?
The reason for the duplicate names is the backend (PHP) is leveraging this functionallity to auto parse the parameters into arrays...which requires the syntax above.
Big picture is- I'm trying to add/remove "filters" from this array-to-be. Also, some filter categories could have matching values so I don't want remove by value either. I am open to considering an entirely new approach...just trying to do it in the least hacky way.
-- Edit --
For any Laravel users, I recommend not using the index-less syntax. Just use color[0]=, color[1]= etc. I didn't realize laravel supports both syntaxes.
To remove a specific key/value pair, loop over the entries, filter out the unwanted one(s) and create a new URLSearchParams:
function deleteParamsEntry(params, key, value) {
const newEntries = Array.from(params.entries()).filter(
([k, v]) => !(k === key && v === value)
);
return new URLSearchParams(newEntries);
}
const query = "?color[]=Black&color[]=Green&material[]=Steel";
const params = new URLSearchParams(query);
const newParams = deleteParamsEntry(params, "color[]", "Green");
console.log(newParams.toString());
Try this approach:
const deleteURLParamsByNameAndValue = (urlString, paramName, paramValue) => {
const url = new URL(urlString)
const params = url.searchParams
const newParamArray = []
for (var kvPair of params.entries()) {
const k = kvPair[0]
const v = kvPair[1]
if (k!==paramName || v!==paramValue) {
newParamArray.push(kvPair)
}
}
const newSearch = new URLSearchParams(newParamArray)
return decodeURI(`${url.origin}${url.pathname}?${newSearch}`)
}
const urlString = 'https://example.com/path1/path2?color[]=Black&color[]=Green&material[]=Steel'
deleteURLParamsByNameAndValue(urlString,'color[]','Black')
// returns 'https://example.com/path1/path2?color[]=Green&material[]=Steel'

Javascript node.js regex url matching

So pretty much I have an inputted URL and I am trying to see if it starts with any of the following URLs:
"https://open.spotify.com/playlist/",
"https://www.youtube.com/watch",
"https://youtu.be/",
"https://open.spotify.com/track/",
"https://youtube.com/playlist",
So how it should work is if I were to input "https://open.spotify.com/track/1vrd6UOGamcKNGnSHJQlSt?si=61680eaef0ac419e" it would return that it matched "https://open.spotify.com/track/".
If I were to input "https://youtu.be/5qap5aO4i9A" it would return "https://youtu.be/".
So far I have
url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)
url.match(/^(https?:\/\/)?(www\.)?(m\.)?(youtube\.com|youtu\.?be)\/.+$/gi)
but it's not taking me down the right path and I am extremely lost. Thank you!
Since you need to get the specific prefix that matched, checking with startsWith would probably be simpler than using a regular expression:
const prefixes = [
"https://open.spotify.com/playlist/",
"https://www.youtube.com/watch",
"https://youtu.be/",
"https://open.spotify.com/track/",
"https://youtube.com/playlist",
];
function getPrefix(url) {
const urlLower = url.toLowerCase();
return prefixes.find((prefix) => urlLower.startsWith(prefix));
}
getPrefix("https://open.spotify.com/track/1vrd6UOGamcKNGnSHJQlSt?si=61680eaef0ac419e"); // "https://open.spotify.com/track/"
getPrefix("https://youtu.be/5qap5aO4i9A"); // "https://youtu.be/"
You should not use regex for that purpose you are using. Since you have all the list of urls you have to match against. You just have to check with the url you receive.
const list = ["https://open.spotify.com/playlist/",
"https://www.youtube.com/watch",
"https://youtu.be/",
"https://open.spotify.com/track/",
"https://youtube.com/playlist",
];
function getMeMatchedURL(url) {
const matchedURL = list.filter(item => {
return url.substring(0, item.length) === item;
});
console.log(matchedURL);
}
getMeMatchedURL("https://open.spotify.com/track/1vrd6UOGamcKNGnSHJQlSt?si=61680eaef0ac419e");
getMeMatchedURL("https://youtu.be/5qap5aO4i9A");
From this you will get the url it matches, if it return empty array then it didn't match any of the list.

How to use reduce and the ramda "hex2color" function to count list of hex values than have r in their color name?

"Use reduce and the hex2color function to count list of hex values than have r in their name";
My current attempt is below. The first piece I know needs to be fixed is the filter function. I need to be able to filter out any colors that have the letter "r", but cannot seem to find a way to easily fit that into the filter function. It could easily be a syntax issue as I think I am asking the filter to find any strings that === "r", even though I am trying to use "contains" to solve that and have it check the whole color word.
Once the filter function is working, I assume the next step is to simply use the reduce function, then compose them together. ( I could be way off off, however).
I am quite new to programming, any insight is extremely welcome. Thanks!!
const exercise3 = _ => {
const hexes = ["#0000ff", "#f5f5dc", "#cd853f", "#663399", "#ffa500"];
const letter = "r";
const mapper = hex2color;
console.log(map(mapper, hexes)); //blue,beige,peru,rebeccapurple,orange
const filterer = el => contains(hex2color(el), letter);
console.log(filter(filterer, hexes)); //yields nothing, I assume to using the filter wrong with "r".
const reducer = (acc, el) => acc + 1;
const mappedFn = map(mapper);
const filtererFn = filter(filterer);
const reducerFn = reduce(reducer, 0);
const composedFn = compose(reducerFn, filtererFn, mappedFn);
return composedFn(hexes);
};

What's the best way to delete specific characters in a JavaScript array?

Currently, I have a huge JavaScript array where each element is like this:
[{"open":235.86,
"high":247.13,
"low":231.5,
"close":244.1,
"volume":55025735,
"date":"2019-05-01T21:00:00.000Z"}
...
I need to remove everything except the price after high. What is the most efficient way I can do this?
I've tried popping the individual elements, but I can't help but feel as if there is a more efficient/easier way to do this.
So hopefully the ending array would just be [235.86].
The below code should work. It's efficient enough :D
for (i in arrayName){
// Loops through array
delete arrayName[i].high
delete arrayName[i].low
delete arrayName[i].close
delete arrayName[i].volume
delete arrayName[i].date
// Deletes unwanted properties
}
console.log(arrayName)
// Print output
One potential solution would be to map the array to a new array like so:
const yourArray = [
{"open":235.86, "high":247.13, "low":231.5, "close":244.1, "volume":55025735},
{"open":257.52, "high":234.53, "low":220.2, "close":274.1, "volume":23534060},
]
const mappedArray = yourArray.map(el => el.open);
// mappedArray = [235.86, 257.52]
Check out the MDN documentation for the map method, Array.prototype.map()
Note: The above example uses ECMAScript 6 arrow functions and implicit returns. It is functionally equivalent to:
const yourArray = [
{"open":235.86, "high":247.13, "low":231.5, "close":244.1, "volume":55025735},
{"open":257.52, "high":234.53, "low":220.2, "close":274.1, "volume":23534060},
]
const mappedArray = yourArray.map(function(el){
return el.open
});
You can use reduce for this scenario. Example
var temp = [{"open":235.86, "high":247.13, "low":231.5, "close":244.1, "volume":55025735, "date":"2019-05-01T21:00:00.000Z"}];
var highValArray = temp.reduce((arr, t) => {
return arr.concat(t['high']);
}, []);
You can learn more about reduce function at the MDN website.
This should work:
your_array.map((item) => {
return item.high
})

Categories

Resources