String replace in JavaScript (like Query Binding) [duplicate] - javascript

This question already has answers here:
How can I do string interpolation in JavaScript?
(21 answers)
Closed 3 years ago.
Thank you for answering my question, I think this is not interpolation so I change the title and before you mark this as duplicate as string interpolation in JavaScript please read the question carefully, because I already read the other interpolation question for JavaScript but not one of them is have the same way that I want for my code (I tell the reason on the question), and I don't want to use Plugin.
Hi all, first I want you to know about my purpose in this code, you can tell this main reason is to build Query Binding for Express with MySQL, but I will use this code for other reason also.
I want to know about string interpolation in Javascript / Typescript that will work like Query Binding in code in Code Igniter source
// Code 1
let person = 'ujang'
let age = 23
console.log("Hello, %s. You're age is %d years old.", person, age)
// Hello, ujang. You're age is 23 years old.
// The function is similiar to this code
// $sql = "insert into tbl_user (name, age, groupname) values (?, ?, ?)";
// $this->db->query($sql,array('codeigniter, 35, 'Group 1'));
As can you see in above code I use console.log and it's working as I want it, but because the console.log is void and not returning any value I can't use it in real condition.
// Code 2
const str = 'helow, %s. and you want %d piece of cake.?'
const name = 'ujang'
const want = 13
const myFunction = (value, ...optionalParams) => {
// The function I want is similiar with Query Binding in Code Igniter
// And it can handle dynamicly params
// This only sample
value = value.replace('%s', optionalParams[0])
value = value.replace('%d', optionalParams[1])
return value
}
myFunction(str, name, want)
// helow, ujang. and you want 13 piece of cake.?
In Code 2 I'll try making a function, that working as expected, but only for static params.
// Code 3
const names = 'ujang'
const arg1 = 'good'
const argN = 'better'
const dontWantFunction = (value, arg1, argN) => {
return `helow, ${value}, this function is ${arg1} but any ${argN} solution.?`
}
dontWantFunction(names, arg1, argN)
// helow, ujang, this function is good but any better solution.?
In Code 3 is function that I don't really want, because is hard to manage and have more hardcode text inside the function.
Is anyone know how to fill myFunction in Code 2.?
or anyone working on similar code.?
or know some documentation / article that will lead me to this solution.?
I'am waiting for your response that will help me a lot,
Thank you for attention.

You can try something like this, where we take out the values from optionalParams in sequential manner and replace on matching value
const str = 'helow, {{value}}. and you want {{value}} piece of cake.?'
const name = 'ujang'
const want = 13
const myFunction = (value, ...optionalParams) => {
return value.replace(/\{\{value\}\}/g, (m) => optionalParams.shift() || m)
}
console.log(myFunction(str, name, want))

Related

JavaScript RegEx: How do I utilise named capture groups? [duplicate]

This question already has answers here:
Javascript: Named Capture Groups
(2 answers)
Named capturing groups in JavaScript regex?
(10 answers)
Closed last month.
I am currently working at a Plugin for RPG Maker MZ and for that, i learned how to use RegEx for analyzing the Content of a Notetag. While my first try with them was actually pretty good, i assume it didn't used the full potential of RegEx and because i need to expand the my RegEx anyway so the user has more options, i wanted to try out named capture groups for better readability and easier access for me as a developer.
Unfortionatly, i wasnt able to find out how to get the "group" object of the objects i got from the Iterator from matchAll(). So my question would be how to analyse the content of a named capture group in javascript.
Important: as far as i saw, the other questions didnt answer the question why i wasnt be able to find the right group object. also, most of the answers are with the exec function instead of the matchAll function.
The for this part relevant Code is:
const regex1new = /(?<ItemCategory>Item|Armor|Weapon)\s*:\s*(?<ID>\d+)\s*(?<Weight>w:(?<WeightFactor>\d+))?/gm;
let foundTagEntrysList = Array.from(this.enemy().meta.HellsCommonDropList.matchAll(regex1new), entry => entry[0]); //If you wanna reproduce this, just replace this.enemy().meta.HellsCommonDropList with a string
newTagsAnalyser();
function newTagsAnalyser() {
foundTagEntrysList.forEach(matchedElement => {
let Item;
let Weight;
let ID = matchedElement.groups.ID;
switch (matchedElement.groups.ItemCategory) {
case "Item":
Item = $dataItems[ID];
break;
case "Weapon":
Item = $dataWeapon[ID];
break;
case "Armor":
Item = $dataArmor[ID];
break;
default:
break;
}
if (typeof matchedElement.groups.Weight !== 'undefined'){
Weight = matchedElement.groups.WeightFactor;
}
commonItemDataMap.set(Item, Weight);
});
}
What did i expected?
That the matechedElement.group.xxx returnes the content of the group that is named xxx.
What was the result?
rmmz_managers.js:2032 TypeError: Cannot read property 'ID' of undefined

URL Parse Exercise (JavaScript)

So here is a description of the problem that I've been talked to solve:
We need some logic that extracts the variable parts of a url into a hash. The keys
of the extract hash will be the "names" of the variable parts of a url, and the
values of the hash will be the values. We will be supplied with:
A url format string, which describes the format of a url. A url format string
can contain constant parts and variable parts, in any order, where "parts"
of a url are separated with "/". All variable parts begin with a colon. Here is
an example of such a url format string:
'/:version/api/:collection/:id'
A particular url instance that is guaranteed to have the format given by
the url format string. It may also contain url parameters. For example,
given the example url format string above, the url instance might be:
'/6/api/listings/3?sort=desc&limit=10'
Given this example url format string and url instance, the hash we want that
maps all the variable parts of the url instance to their values would look like this:
{
version: 6,
collection: 'listings',
id: 3,
sort: 'desc',
limit: 10
}
So I technically have a semi-working solution to this but, my questions are:
Am I understanding the task correctly? I'm not sure if I'm supposed to be dealing with two inputs (URL format string and URL instance) or if I'm just supposed to be working with one URL as a whole. (my solution takes two separate inputs)
In my solution, I keep reusing the split() method to chunk the array/s down and it feels a little repetitive. Is there a better way to do this?
If anyone can help me understand this challenge better and/or help me clean up my solution, it would be greatly appreciated!
Here is my JS:
const obj = {};
function parseUrl(str1, str2) {
const keyArr = [];
const valArr = [];
const splitStr1 = str1.split("/");
const splitStr2 = str2.split("?");
let val1 = splitStr2[0].split("/");
let val2 = splitStr2[1].split("&");
splitStr1.forEach((i) => {
keyArr.push(i);
});
val1.forEach((i) => {
valArr.push(i);
});
val2.forEach((i) => {
keyArr.push(i.split("=")[0]);
valArr.push(i.split("=")[1]);
});
for (let i = 0; i < keyArr.length; i++) {
if (keyArr[i] !== "" && valArr[i] !== "") {
obj[keyArr[i]] = valArr[i];
}
}
return obj;
};
console.log(parseUrl('/:version/api/:collection/:id', '/6/api/listings/3?sort=desc&limit=10'));
And here is a link to my codepen so you can see my output in the console:
https://codepen.io/TOOTCODER/pen/yLabpBo?editors=0012
Am I understanding the task correctly? I'm not sure if I'm supposed to
be dealing with two inputs (URL format string and URL instance) or if
I'm just supposed to be working with one URL as a whole. (my solution
takes two separate inputs)
Yes, your understanding of the problem seems correct to me. What this task seems to be asking you to do is implement a route parameter and a query string parser. These often come up when you want to extract data from part of the URL on the server-side (although you don't usually need to implement this logic your self). Do keep in mind though, you only want to get the path parameters if they have a : in front of them (currently you're retrieving all values for all), not all parameters (eg: api in your answer should be excluded from the object (ie: hash)).
In my solution, I keep reusing the split() method to chunk the array/s
down and it feels a little repetitive. Is there a better way to do
this?
The number of .split() methods that you have may seem like a lot, but each of them is serving its own purpose of extracting the data required. You can, however, change your code to make use of other array methods such as .map(), .filter() etc. to cut your code down a little. The below code also considers the case when no query string (ie: ?key=value) is provided:
function parseQuery(queryString) {
return queryString.split("&").map(qParam => qParam.split("="));
}
function parseUrl(str1, str2) {
const keys = str1.split("/")
.map((key, idx) => [key.replace(":", ""), idx, key.charAt(0) === ":"])
.filter(([,,keep]) => keep);
const [path, query = ""] = str2.split("?");
const pathParts = path.split("/");
const entries = keys.map(([key, idx]) => [key, pathParts[idx]]);
return Object.fromEntries(query ? [...entries, ...parseQuery(query)] : entries);
}
console.log(parseUrl('/:version/api/:collection/:id', '/6/api/listings/3?sort=desc&limit=10'));
It would be even better if you don't have to re-invent the wheel, and instead make use of the URL constructor, which will allow you to extract the required information from your URLs more easily, such as the search parameters, this, however, requires that both strings are valid URLs:
function parseUrl(str1, str2) {
const {pathname, searchParams} = new URL(str2);
const keys = new URL(str1).pathname.split("/")
.map((key, idx) => [key.replace(":", ""), idx, key.startsWith(":")])
.filter(([,,keep]) => keep);
const pathParts = pathname.split("/");
const entries = keys.map(([key, idx]) => [key, pathParts[idx]]);
return Object.fromEntries([...entries, ...searchParams]);
}
console.log(parseUrl('https://www.example.com/:version/api/:collection/:id', 'https://www.example.com/6/api/listings/3?sort=desc&limit=10'));
Above, we still need to write our own custom logic to obtain the URL parameters, however, we don't need to write any logic to extract the query string data as this is done for us by using URLSearchParams. We're also able to lower the number of .split()s used as we can obtain use the URL constructor to give us an object with a parsed URL already. If you end up using a library (such as express), you will get the above functionality out-of-the-box.

Pick out words in a string that are in array

I have spent hours, close to 8 hours none stop on this, I am trying to use jQuery/JS to create two arrays, one which is dynamic as it is loading a chat script and will be split by whitespace in to an array, for example:
String: Hello my name is Peter
Converted to (message) array: ['hello','my','name','is','peter'];
I have a set array to look out for specific words, in this example let us use:
(find array) ['hello','peter'] however, this array is going to contain up to 20 elements and I need to ensure it searches the message array efficiently, please help.
I can help you with that.
var arrayOfWords = $(".echat-shared-chat-message-body").last().text().split(" ");
That code is actually working! i went to an open chat in this website so I can tested.
So just replace the word REPLACE with your DOM object :)
var arrayOfWords = $("REPLACE").last().text().split(" ");
If I understood well, you're asking to filter an array of string (from an incoming string) given a second array.
In your described case you'll certainly not have to worry about efficiency, really. Unless your incoming message is allowed to be very very big.
Given that, there is a dozen of options, I think this is the most succinct:
const whitelist = [
'hello',
'peter'
]
const message = 'hello my name is Peter'.split(' ')
const found = message.filter(function(word) {
return whitelist.indexOf(word) > -1
}
You can treat invariant case:
const whitelistLower = whitelist.toLowerCase()
const foundInvariantCase = message.filter(function(word) {
return whitelist.indexOf(word.toLowerCase()) > -1
}
Or use ESS Set:
const whitelistSet = new Set(whitelist)
const found = message.filter(function(word) {
return whitelistSet.has(word)
}

How to Test if a String Has an Array Entry [duplicate]

This question already has answers here:
Javascript- Matching values from array to substring of variable
(3 answers)
Closed 4 years ago.
I'm creating a Discord bot with Discord.js that catches whenever someone swears in a message. I have an array that's full of common swear words, abbreviations, racial and sexual slurs, etc. that I want it to catch.
const SwearWords = ["a##","ba##ard","bi###","c#ck","c#nt","d#ck","f#ck","gay","k#ke","n#gg","omfg","sh#t","wtf"];
(the array doesn't have all the hashtags, I just added them in for the post)
What I tried using originally was if (lcMsg.includes(SwearWords)) {return;} with lcMsg being message.content.toLowerCase(); so that it can catch users swearing no matter how they capitalize it. But that didn't work so I tried using .entries() and .every() after Google-ing an answer (and I never found any).
I imagine .map() would work? I don't know because I haven't learned how to use that. If someone could help me figure this out that'd be great.
The array .some method will be helpful here. Combine that with your .includes to see if any of those words are present in the message:
const SwearWords = ["a##","ba##ard","bi###","c#ck","c#nt","d#ck","f#ck","gay","k#ke","n#gg","omfg","sh#t","wtf"];
const saltyMessage = "wtf, git gud scrub";
const niceMessage = "gg wp";
function hasBadWord(msg) {
return SwearWords.some(word => msg.includes(word));
}
console.log("Message and has swear word?:", saltyMessage, " -> ", hasBadWord(saltyMessage));
console.log("Message and has swear word?:", niceMessage, " -> ", hasBadWord(niceMessage));
Additionally, you can find which word the message had by using .find instead of .some:
const SwearWords = ["a##","ba##ard","bi###","c#ck","c#nt","d#ck","f#ck","gay","k#ke","n#gg","omfg","sh#t","wtf"];
const saltyMessage = "wtf, git gud scrub";
const niceMessage = "gg wp";
function whichBadWord(msg) {
return SwearWords.find(word => msg.includes(word));
}
console.log("Message and has swear word?:", saltyMessage, " -> ", whichBadWord(saltyMessage));
console.log("Message and has swear word?:", niceMessage, " -> ", whichBadWord(niceMessage));
You need to use the function some and function includes
lcMsg.replace(/\s+/g, ' ').split(' ').some((w) => SwearWords.includes(w));
Look how the variable lcMsg is being prepared to loop over its words.

Query syntax for JSON lookup data with var ( not condition ) [duplicate]

This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 6 years ago.
I'm trying to filter some JSON data, but I would like the lookup to be based on selection of a drop down. However, I just can't get the syntax correct when trying to do this. Currently the following works in my code, great:
var as = $(json).filter(function (i, n) {
return (n.FIELD1 === "Yes"
});
However, what I would like to do is replace the FIELD1 value with a var from the drop down. Something like this following, which is not working:
var dropdownResult = "FIELD1";
var as = $(json).filter(function(i, n) {
return (n.dropdownResult === "Yes"
});
I'm trying to get the var to become the field name after the n. but it's not working.
Thanks for your time. Sorry if this has been answered many times before and is obvious to you.
To use a variable value as the key of an object you should use bracket notation, like this:
var dropdownResult = "FIELD1";
var as = $(json).filter(function(i, n) {
return n[dropdownResult] === "Yes";
});
I removed the extraneous ( you left in your code - I presume this was just a typo as it would have created a syntax error and stopped your code from working at all.
Also note that it's much better practice to use a boolean value over a string 'Yes'/'No'

Categories