Dynamic masked input according to data [duplicate] - javascript

This question already has answers here:
Dynamic regex pattern in JavaScript
(4 answers)
Closed 2 years ago.
I have a response and it returns "XXX-XXX" or "XX-XXXX"
const formatUnitCode = (value, format) => {}
So basically, I want to see as formatUnitCode("123456", "XX-XXX") --> "12-3456"
I don't want to use if else because it may come in the future as XX-XX-XX
Can someone help me create this function?
I tried to do with regex but I think it is not possible to pass variable instead of {2} and {4}
const formatCode = (val) => val.replace(/(\d{2})(\d{4})/g, "$1-$2");

Is this what you would like to do?
const func = (val, first_digit) => {
let regex = new RegExp("(\\d{" + first_digit + "})(\\d{" + (6-first_digit) + "})","g");
return val.replace(regex,"$1-$2");
};

You can use simple for loop make a dynamic string format method.
const formatUnitCode = (str, format) => {
let result = '';
let j = 0;
for (let i = 0, l = format.length; i < l; i += 1) {
if (format[i] === 'X') {
result += str[j];
j += 1;
} else result += format[i];
}
for (; j < str.length; j += 1) result += str[j];
return result;
};
console.log(formatUnitCode('123456', 'XX-XXX'));
console.log(formatUnitCode('123456', 'XXX-XXX'));
console.log(formatUnitCode('123456', 'XX-XXXX'));
console.log(formatUnitCode('123456', 'XX-XX-XX'));

You can't use variables in RegExp literals, but you can when you use the RegExp() constructor to build the pattern as a string instead.
const formatStr = (val, format) => {
let ptn = format.split('-').map(part => '(.{'+part.length+'})').join('');
match = val.match(new RegExp(ptn));
match && console.log(match.slice(1).join('-'));
};
It's instructive to console.log() the ptn var to see what's happening there. We're using your arbitrary "X"-based format to derive a new, dynamic RegExp which will be used in a multi-match RegExp to grab the parts.
formatStr('123456', 'xxx-xxx'); //"123-456"
formatStr('123456', 'xx-xxxx'); //"12-3456"

This should work for any mask regardless of the letters used (you can control that behaviour by changing matcher regex). Personally, I think it's a more elastic approach than just trying to match the given mask with a regex.
const replaceWithFiller = (filler, str, matcher = /[a-zA-z]/g) => {
const arr = filler.split('');
return str.replace(matcher, () => arr.shift());
};
console.log(replaceWithFiller('123456', 'XXX-XXX')); //"123-456"
console.log(replaceWithFiller('123456', 'XX-XX-XX')); // "12-34-56"
console.log(replaceWithFiller('123456', 'XX-XXXX')); //"12-3456"
console.log(replaceWithFiller('123456', 'aa-aaaa')); // also "12-3456"

you can pass parameters to your regex using template literals:
const formatCode = (val, format) => {
const lengthFirstBlock = format.indexOf('-');
const lehgthSecondBlock = format.length - format.indexOf('-');
const regex = new RegExp(`(\\d{${lengthFirstBlock}})(\\d{${lehgthSecondBlock}})`, 'g');
return val.replace(regex, "$1-$2");
}
console.log(formatCode("123456", "XX-XXX"))
console.log(formatCode("123456", "XXX-XX"))

Related

Grab substring after and before two specific characters in javascript

i have a url search key like that:
?retailerKey=A and i want to grab the retailerKey substring. All examples that i saw are having as example how to take before the char with the indexOf example. How can i implement this to have this substring from the string ?retailerKey=A
You could split() the string on any ? or = and take the middle item ([1]) from the outcome array.
const data = "?retailerKey=A";
const result = data.split(/[\?=]/)[1];
console.log(result);
If you have multiple params, creating an object fromEntries() would be interesting.
const data = "?retailerKey=A?otherKey=B";
const keyVals = data.split(/[\?=]/).filter(x => x); // keys and values
const result = Object.fromEntries(keyVals.reduce((acc, val, i) => {
// create entries
const chunkI = Math.floor(i / 2);
if (!acc[chunkI]) acc[chunkI] = [];
acc[chunkI].push(val);
return acc;
}, []));
console.log(result);
use regex expression.
Following will return the value between character ? and =
var result = "?retailerKey=A".match(/\?(.*)\=/).pop();
console.log(result);
If you would like to always get the string between your query sign and equal sign ?ThisString=
then you can simply use indexOf for example
str.slice(str.indexOf('?')+1,str.indexOf('='))
Using library could be a better choice but to do it from scratch : I suggest to use split with a regular expression.
// split for char equals to ? or & or =;
const url = '/toto?titi=1&tata=2';
const args = url.split(/[\?\&\=]/);
// shift the first element of the list since it the base url before "?"
args.shift();
// detect malformed url
if (args.length % 2) {
console.error('malformed url', args);
}
const dictArgs = {};
for (let i = 0; i < args.length /2; i ++) {
const key = args[2*i];
const val = args[2*i+1];
dictArgs[key] = val;
}
console.log(dictArgs);

Splitting a string, duplicating each character and re-joining to form new string Abcd would become AAbbccdd [duplicate]

This question already has answers here:
Concatenate string through for loop
(4 answers)
Closed 1 year ago.
I need to be able to duplicate the characters of a string and recombine using my function so Abcd would become AAbbccdd etc..
function doubleChar(str) {
let output = str.split("");
let result = "";
for (i = 0; i < str.length; i++) {
result = output[i] + output[i]
}
return (result)
}
console.log(doubleChar("Abcd"));
I know this is is a completely different approach but that is how I (shorthand fanboy) would do it:
const doubleChar = (str) => str.split("").reduce((a, b) => a + b + b, "");
console.log(doubleChar("Abcd"));
If you want to stick to your version. This is how you could make it work:
function doubleChar(str) {
let output = str.split("");
let result = "";
for (i = 0; i < str.length; i++) {
result += output[i] + output[i]; // <- change = to +=
}
return result;
}
console.log(doubleChar("Abcd"));
You're replacing result every time. Change the result = to result += so you append to it instead.
replace
result = output[i] + output[i]
with
result = result + output[i] + output[i]
You can split the string into an array of characters and use flatMap() to duplicate the items, then join back together:
function doubleChar(str) {
return str.split("").flatMap(i => [i,i]).join('')
}
console.log(doubleChar("Abcd"));
Another alternative to do it is to map each character and return it x2:
function doubleChar(str) {
return str.split("").map(c => c+c).join("");
}
console.log(doubleChar("Abcd"));
Good question Jonathan. I would recommend looking into some string functions as well as some array functions.
Here are a few to get started ->
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
An approach with these functions could be as simple as
function doubleChar(str) { // "abc"
return str.split('') // ["a","b","c"]
.map(char => char.repeat(2)) // ["aa","bb","cc"]
.join(''); // "aabbcc"
}
To simplify your approach, you can iterate over the string character-by-character by using a for of loop
function doubleChar(str) {
let doubledStr = '';
for (let character of str) {
doubledStr += character.repeat(2);
}
return doubledStr;
}

Javascript: converting string to an array

This is one of my function for a calculator project. First I needed to convert the input string into an array, and do the operation later. (assuming that input has only numbers and '+' sign for now.
My question here is, how do I improve this code? What are the other ways to deal with this problem? (Time complexity, cleanness, shorter code.......whatever)
function convertArray(input) {
let array = [];
let num = "";
for (let i = 0; i < input.length; i++) {
if (input.charAt(i) == '+') {
array.push(input.charAt(i));
} else {
do {
num += input.charAt(i);
i++;
} while (i < input.length && input.charAt(i) !== '+');
array.push(num);
num = "";
i--;
}
}
return array;
}
console.log(convertArray("10+2+3000+70+1"));
You could split with a group. this add the group as well to the array.
For other calculation signs, you could add them to the brackets.
const convertArray = string => string.split(/([+])/);
console.log(convertArray("10+2+3000+70+1"));
const q = prompt('Sum?');
alert('Answer: ' + eval(q));
Would not recommend using eval, but if all you need is a quick and dirty trick, it works.
Personally, I'd recommend a library such as Math.js, but any will do.
If you really need to do this by yourself for a project, I'd recommend checking out the answers here: Evaluating a string as a mathematical expression in JavaScript.
Hope you succeed in whatever you're planning on doing.
It seems the complexity must have something to do with your wish to determing operators. In your code you just push them all into the array. To do that is like
const re = /((\d+)|([^\d]+))/g
const convertArray = str => {
let match, arr=[];
while (match = re.exec(str)) {
arr.push(match[1]) // here you can determine if you have an operator
console.log(match[1],"Operator?",!/^\d+$/.test(match[1]))
}
return arr
}
const str = "10+2+3000+70+1";
console.log(convertArray(str));

Algorithm challenge: Repeating a string

just learning JS and am going through Algorithm challenges.
The below code should repeat a string (str) x (num) times.
So for example repeatStringNumTimes('*', 3) should be '***'.
The below code does that... but there is an 'undefined' word that appears in the beginning of the output. Why is that?! I've defined all variables...
function repeatStringNumTimes(str, num) {
let len = str.length;
let string;
for (let i = 0; i < num; i++) {
for (let x = 0; x < len; x++) {
string += str[x];
}
}
return string;
}
console.log(repeatStringNumTimes('*', 10));
I've defined all variables
Yes you define it, but not initialize.
Default initalization in javascript is undefined.
So, let a; equals to let a = undefined;
You should initialize your strings with empty string:
let string = '';
Just a note:
Modern javascript engines have String.prototype.repeat method for that task:
console.log('*'.repeat(10)); // **********
Ok so, in order to make this work I added
let string = "";
I'm not sure why that works though. Any insight from someone more experienced would be greatly appreciated.
You probably need to declare string:
let string = "";
UPDATE:
That is because of this line:
string += str[x];
Which equates to:
string = string + str[x];
// equivalent to string = undefined + str[x]
You are assigning an undefined string to itself (+ str[x]), if that makes sense.
Traditional approach using while
const repeatStringNumTimes = (str, num) => {
let res = str
while (--num) res += str
return res
}
console.log(repeatStringNumTimes('*', 10))
Using String.prototype.repeat
const repeatStringNumTimes = (str, num) => str.repeat(num)
console.log(repeatStringNumTimes('*', 10))
Using String.prototype.padStart() or String.prototype.padEnd()
const repeatStringNumTimes = (str, num) => ''.padStart(num, str)
console.log(repeatStringNumTimes('*', 10))
Using Array.prototype.join()
const repeatStringNumTimes = (str, num) => Array(num).join(str)
console.log(repeatStringNumTimes('*', 10))

javascript transform text array

I use a react component which work like this
<FontAwesomeIcon icon={faCoffee} />
it take a font awesome icon let say address-book it add fa before, delete hyphen and uppercase the first letter of each world.
address-book become faAddressBook
copyright become faCopyright
arrow-alt-circle-down become faArrowAltCircleDown
Is it possible to create a javascript function which take an array like this
["address-book","copyright","arrow-alt-circle-down"]
and transform it in an array like that
["faAddressBook","faCopyright","faArrowAltCircleDown"]
There are some ways to do it. Like using regular expression. However, your requirement is simple, so it can be easily done with JavaScript split method. Please check the following implemented function.
function formatArray(str)
{
str = str.split("-");
for (var i = 0, x = str.length; i < x; i++) {
str[i] = str[i][0].toUpperCase() + str[i].substr(1);
}
return 'fa' + str.join("");
}
var givenArr = ["address-book","copyright","arrow-alt-circle-down"];
for( var i = 0; i < givenArr.length; i++) {
givenArr[i] = formatArray(givenArr[i]);
console.log(givenArr[i]+ '\n');
}
You can do the following with Array's map() and forEach():
var arr = ["address-book","copyright","arrow-alt-circle-down"];
function upperCase(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
var outPut = arr.map(function(item){
var temp = item.split('-');
var temp2 = [];
temp.forEach(function(data){
temp2.push(upperCase(data))
});
return 'fa' + temp2.join('')
})
console.log(outPut);
Looks like there's two essential steps here. First, we need to prepend fa onto each string, and second, we need to convert them from kebab-case to camelCase.
So just write a function for each of those conversions, then run your array through a map using each of them:
const kebabs = ["address-book","copyright","arrow-alt-circle-down"];
function kebabToCamel(str) {
return str.replace(/-(\w)/g, m => m[1].toUpperCase());
}
function prependFa(str) {
return "fa-" + str;
}
console.log(kebabs.map(prependFa).map(kebabToCamel))

Categories