put dash after every n character during input from keyboard - javascript

$('.creditCardText').keyup(function() {
var foo = $(this).val().split("-").join(""); // remove hyphens
if (foo.length > 0) {
foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
}
$(this).val(foo);
});
I found this tutorial on putting dash after every 4 character from here my question is what if the character interval is not constant like in this example it is only after every 4 what if the interval is 3 characters "-" 2 characters "-" 4 characters "-" 3 characters "-" so it would appear like this 123-12-1234-123-123.

In this case, it is more convenient to just write normal code to solve the problem:
function format(input, format, sep) {
var output = "";
var idx = 0;
for (var i = 0; i < format.length && idx < input.length; i++) {
output += input.substr(idx, format[i]);
if (idx + format[i] < input.length) output += sep;
idx += format[i];
}
output += input.substr(idx);
return output;
}
Sample usage:
function format(input, format, sep) {
var output = "";
var idx = 0;
for (var i = 0; i < format.length && idx < input.length; i++) {
output += input.substr(idx, format[i]);
if (idx + format[i] < input.length) output += sep;
idx += format[i];
}
output += input.substr(idx);
return output;
}
$('.creditCardText').keyup(function() {
var foo = $(this).val().replace(/-/g, ""); // remove hyphens
// You may want to remove all non-digits here
// var foo = $(this).val().replace(/\D/g, "");
if (foo.length > 0) {
foo = format(foo, [3, 2, 4, 3, 3], "-");
}
$(this).val(foo);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input class="creditCardText" />
While it is possible to do partial matching and capturing with regex, the replacement has to be done with a replacement function. In the replacment function, we need to determine how many capturing group actually captures some text. Since there is no clean solution with regex, I write a more general function as shown above.

You can split it using a regular expression. In this case, I'm using a expression to check for non-spaces with interval 3-2-4-3.
The RegExp.exec will return with a "match" array, with the first element containing the actual string. After removing the first element of the match, you can then join them up with dashes.
var mystring = "123121234123"
var myRegexp = /^([^\s]{3})([^\s]{2})([^\s]{4})([^\s]{3})$/g
var match = myRegexp.exec(mystring);
if (match)
{
match.shift();
mystring = match.join("-")
console.log(mystring)
}

Per further comments, the op clarified they need a fixed interval for when to insert dashes. In that case, there are several ways to implement it; I think regular expression would probably be the worst, in other words, overkill and overly complication solution.
Some simpler options would be to create a new character array, and in a loop append character by character, adding a dash too every time you get to the index you want. This would probably be the easiest to write and grok after the fact, but a little more verbose.
Or you could convert to a character array and use an 'insert into array at index'-type function like splice() (see Insert Item into Array at a Specific Index or Inserting string at position x of another string for some examples).

Pass the input value and the indexes to append the separator, first, it will remove the existing separators then just append separators on positions indexes.
export function addSeparators(
input: string,
positions: number[],
separator: string
): string {
const inputValue = input.replace(/-/g, '').split(''); // remove existing separators and split characters into array
for (let i = 0; i < inputValue.length; i++) {
if (positions.includes(i)) inputValue.splice(i, 0, separator);
}
return inputValue.join('');
}

Related

How to get odd and even position characters from a string?

I'm trying to figure out how to remove every second character (starting from the first one) from a string in Javascript.
For example, the string "This is a test!" should become "hsi etTi sats!"
I also want to save every deleted character into another array.
I have tried using replace method and splice method, but wasn't able to get them to work properly. Mostly because replace only replaces the first character.
function encrypt(text, n) {
if (text === "NULL") return n;
if (n <= 0) return text;
var encArr = [];
var newString = text.split("");
var j = 0;
for (var i = 0; i < text.length; i += 2) {
encArr[j++] = text[i];
newString.splice(i, 1); // this line doesn't work properly
}
}
You could reduce the characters of the string and group them to separate arrays using the % operator. Use destructuring to get the 2D array returned to separate variables
let str = "This is a test!";
const [even, odd] = [...str].reduce((r,char,i) => (r[i%2].push(char), r), [[],[]])
console.log(odd.join(''))
console.log(even.join(''))
Using a for loop:
let str = "This is a test!",
odd = [],
even = [];
for (var i = 0; i < str.length; i++) {
i % 2 === 0
? even.push(str[i])
: odd.push(str[i])
}
console.log(odd.join(''))
console.log(even.join(''))
It would probably be easier to use a regular expression and .replace: capture two characters in separate capturing groups, add the first character to a string, and replace with the second character. Then, you'll have first half of the output you need in one string, and the second in another: just concatenate them together and return:
function encrypt(text) {
let removedText = '';
const replacedText1 = text.replace(/(.)(.)?/g, (_, firstChar, secondChar) => {
// in case the match was at the end of the string,
// and the string has an odd number of characters:
if (!secondChar) secondChar = '';
// remove the firstChar from the string, while adding it to removedText:
removedText += firstChar;
return secondChar;
});
return replacedText1 + removedText;
}
console.log(encrypt('This is a test!'));
Pretty simple with .reduce() to create the two arrays you seem to want.
function encrypt(text) {
return text.split("")
.reduce(({odd, even}, c, i) =>
i % 2 ? {odd: [...odd, c], even} : {odd, even: [...even, c]}
, {odd: [], even: []})
}
console.log(encrypt("This is a test!"));
They can be converted to strings by using .join("") if you desire.
I think you were on the right track. What you missed is replace is using either a string or RegExp.
The replace() method returns a new string with some or all matches of a pattern replaced by a replacement. The pattern can be a string or a RegExp, and the replacement can be a string or a function to be called for each match. If pattern is a string, only the first occurrence will be replaced.
Source: String.prototype.replace()
If you are replacing a value (and not a regular expression), only the first instance of the value will be replaced. To replace all occurrences of a specified value, use the global (g) modifier
Source: JavaScript String replace() Method
So my suggestion would be to continue still with replace and pass the right RegExp to the function, I guess you can figure out from this example - this removes every second occurrence for char 't':
let count = 0;
let testString = 'test test test test';
console.log('original', testString);
// global modifier in RegExp
let result = testString.replace(/t/g, function (match) {
count++;
return (count % 2 === 0) ? '' : match;
});
console.log('removed', result);
like this?
var text = "This is a test!"
var result = ""
var rest = ""
for(var i = 0; i < text.length; i++){
if( (i%2) != 0 ){
result += text[i]
} else{
rest += text[i]
}
}
console.log(result+rest)
Maybe with split, filter and join:
const remaining = myString.split('').filter((char, i) => i % 2 !== 0).join('');
const deleted = myString.split('').filter((char, i) => i % 2 === 0).join('');
You could take an array and splice and push each second item to the end of the array.
function encrypt(string) {
var array = [...string],
i = 0,
l = array.length >> 1;
while (i <= l) array.push(array.splice(i++, 1)[0]);
return array.join('');
}
console.log(encrypt("This is a test!"));
function encrypt(text) {
text = text.split("");
var removed = []
var encrypted = text.filter((letter, index) => {
if(index % 2 == 0){
removed.push(letter)
return false;
}
return true
}).join("")
return {
full: encrypted + removed.join(""),
encrypted: encrypted,
removed: removed
}
}
console.log(encrypt("This is a test!"))
Splice does not work, because if you remove an element from an array in for loop indexes most probably will be wrong when removing another element.
I don't know how much you care about performance, but using regex is not very efficient.
Simple test for quite a long string shows that using filter function is on average about 3 times faster, which can make quite a difference when performed on very long strings or on many, many shorts ones.
function test(func, n){
var text = "";
for(var i = 0; i < n; ++i){
text += "a";
}
var start = new Date().getTime();
func(text);
var end = new Date().getTime();
var time = (end-start) / 1000.0;
console.log(func.name, " took ", time, " seconds")
return time;
}
function encryptREGEX(text) {
let removedText = '';
const replacedText1 = text.replace(/(.)(.)?/g, (_, firstChar, secondChar) => {
// in case the match was at the end of the string,
// and the string has an odd number of characters:
if (!secondChar) secondChar = '';
// remove the firstChar from the string, while adding it to removedText:
removedText += firstChar;
return secondChar;
});
return replacedText1 + removedText;
}
function encrypt(text) {
text = text.split("");
var removed = "";
var encrypted = text.filter((letter, index) => {
if(index % 2 == 0){
removed += letter;
return false;
}
return true
}).join("")
return encrypted + removed
}
var timeREGEX = test(encryptREGEX, 10000000);
var timeFilter = test(encrypt, 10000000);
console.log("Using filter is faster ", timeREGEX/timeFilter, " times")
Using actually an array for storing removed letters and then joining them is much more efficient, than using a string and concatenating letters to it.
I changed an array to string in filter solution to make it the same like in regex solution, so they are more comparable.

How to make element in Array change its' place

I'm beginner in JS. I've tried to understand Caesar Cipher ROT13, but it was too complicated for me. So I've tried to write my own code. Here it is below:
function encrip() {
var alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var str = "Ni Hao";
var string = str.toUpperCase();
for (var i = 0; i < string.length; i++) {
for (var k = 0; k < alphabet.length; k++) {
if(string.charAt(i) == alphabet[k]) {
/* console.log(string.charAt(i) + ' ' + alphabet.indexOf(alphabet[k])); */
}
}
}
}
encrip();
But I am stuck. How to do:
1. Get value from var str and then access to var alphabet , after change each letter from var str value to next 3 from alphabet (var str each element's current position would be changed) For example: Input: Ni Hao ==> output: QL KDR
2. Create universal code, I mean, not only for changing position by 3, but when I give value '5', each element would be changed by next 5 positions from alphabet. So output can be changed when I change its' value
I hope I explained everything clearly. Thanks everyone in advance for help!!
you can use the following function to encrypt english words, the 1st parameter is the string to encrypt and the 2nd for shifting
function encryp(str,pos){
var alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var strUC=str.toUpperCase();
var enc="";
for(var i=0;i<strUC.length;i++){
if(strUC.charAt(i)!=" "){
enc+=alpha.charAt((alpha.indexOf(strUC.charAt(i))+pos)%26)
}
else{
enc+=" "
}
// in your case pos=3
}
return enc;
}
console.log(encryp("NiHao",3));
You don't need two for loops to do this. Iterate over the input string and find the index of each character in the alphabet array, if found add the shift to it to get the encrypted character.
To handle overflow use the modulus operator to cycle through the array.
Also I assume that you are not going use any special symbols to do the encryption.
function encrip(string, shift) {
var alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
string = string.toUpperCase();
let arr = [];
for (var i = 0; i < string.length; i++) {
let char = alphabet.indexOf(string[i]) !== -1 ? alphabet[(alphabet.indexOf(string[i]) %26) + shift] : " ";
arr.push(char);
}
let encryp = arr.join("");
console.log(encryp);
return encryp;
}
encrip("Ni Hao", 3);
First of all, instead of your inner for loop scanning the whole alphabet array, you can use the built-in function indexOf:
alphabet.indexOf('K') // returns 10
Secondly, you'll want to build up your enciphered string in a separate variable. For each letter, get the index of that letter in the alphabet, add your cipher offset parameter to that index and add the resulting letter from the alphabet to your new string. An important step is that when you add to the index of the letter, you want to make sure the resulting index is within range for the alphabet array. You can do that using the % (modulo) operator, which will wrap high values back round to the start of the array. In full:
function encipher(input, offset) {
var alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var str = input.toUpperCase();
var result = '';
for (var i = 0; i < str.length; i++) {
letterIndex = alphabet.indexOf(str.charAt(i));
if (letterIndex === -1) {
result += str[i]; // if the letter isn't found in the alphabet, add it to the result unchanged
continue;
}
cipheredIndex = (letterIndex + offset) % alphabet.length; // wrap index to length of alphabet
result += alphabet[cipheredIndex];
}
console.log(result);
}
encipher('Ni Hao', 5); // output: 'SN MFT'

Javascript breaking up string and reverse it

I am trying to figure out how to break up a sting to groups of five and reverse each one individually. I want it to work for any string, (there is no delimiter for splitting)
For example, if the variable is:
Iwanttobreakthisintogroupsoffiveandreverse
I would want it to return:
tnawI erbot ihtka otnis puorg iffos dnaev rever es
How do I go about this?
var str = "Iwanttobreakthisintogroupsoffiveandreverse"
var result = [];
str.replace(/.{1,5}/g, function(m) {
result.push(m.split('').reverse().join(''));
});
result.join(' ');
// "tnawI erbot ihtka otnis puorg iffos dnaev rever es"
var input="Iwanttobreakthisintogroupsoffiveandreverse";
var matches = input.match(/.{1,5}/g);
for (i = 0; i < matches.length; ++i) {
matches[i] = matches[i].split("").reverse().join("");
}
alert(matches);
It pops up tnawI,erbot,ihtka,otnis,puorg,iffos,dnaev,rever,es
You could try this:
var chars = "Iwanttobreakthisintogroupsoffiveandreverse".split('')
var str_rev = []
for (i = 0; i < chars.length; i += 5)
str_rev.push( chars.slice(i, i + 5).reverse().join('') )
Convert to char array using split(''). This allows you to use array methods like reverse and slice
Loop through the char array taking 5 element slices
reverse the elements, join the chars to create a string, and add it to rev_str

Javascript change commas for points and points for commas?

I want to convert all commas in a string in points and vice-versa. However I don't know how to do it since I get all commas or points after the first change.
"1.000,20" should become "1,000.20"
How can this be done?
Try
"1.000,20".replace(/[\.,]/g, function (m) { return m == '.' ? ',' : '.' })
which uses the callback function option of replace()
Try this:
var str = "1,000.20";
//Split into components based on a period
var components = str.split('.');
//Iterate through each component, replacing commas with periods
var length = components.length;
for (var i = 0; i < length; i++) {
components[i] = components[i].replace(",", ".");
}
//Array.join can be slow but still useful - join with commas
str = components.join(",");

How can I parse a string in Javascript?

I have string looking like this:
01
02
03
99
I'd like to parse these to make them into strings like:
1. 2. 3. 99. etc.
The numbers are a maximum of 2 characters. Also I have to parse some more numbers later in the source string so I would like to learn the substring equivalent in javascript. Can someone give me advice on how I can do. Previously I had been doing it in C# with the following:
int.Parse(RowKey.Substring(0, 2)).ToString() + "."
Thanks
Why, parseInt of course.
// Add 2 until end of string
var originalA = "01020399";
for (var i = 0; i < originalA.length; i += 2)
{
document.write(parseInt(originalA.substr(i, 2), 10) + ". ");
}
// Split on carriage returns
var originalB = "01\n02\n03\n99";
var strArrayB = originalB.split("\n");
for (var i = 0; i < strArrayB.length; i++)
{
document.write(parseInt(strArrayB[i], 10) + ". ");
}
// Replace the leading zero with regular expressions
var originalC = "01\n02\n03\n99";
var strArrayC = originalC.split("\n");
var regExpC = /^0/;
for (var i = 0; i < strArrayC.length; i++)
{
document.write(strArrayC[i].replace(regExpC, "") + ". ");
}
The other notes are that JavaScript is weakly typed, so "a" + 1 returns "a1". Additionally, for substrings you can choose between substring(start, end) and substr(start, length). If you're just trying to pull a single character, "abcdefg"[2] will return "c" (zero-based index, so 2 means the third character). You usually won't have to worry about type-casting when it comes to simple numbers or letters.
http://jsfiddle.net/mbwt4/3/
use parseInt function.
parseInt(09) //this will give you 9
var myString = parseInt("09").toString()+". "+parseInt("08").toString();
string = '01\n02\n03\n99';
array = string.split('\n');
string2 = '';
for (i = 0; i < array.length; i++) {
array[i] = parseInt(array[i]);
string2 += array[i] + '. ';
}
document.write(string2);
var number = parseFloat('0099');
Demo
Substring in JavaScript works like this:
string.substring(from, to);
where from is inclusive and to is exclusive. You can also use slice:
string.slice(from, to)
where from is inclusive and to is exclusive. The difference between slice and substring is with slice you can specify negative numbers. For example, from = -1 indicates the last character. from(-1, -3) would give you the last 2 characters of the string.
With both methods if you don't specify end then you will get all the characters to the end.
Paul
Ii they are always 2 digits how about;
var s = "01020399";
var result = []
for (var i = 0; i < s.length; i+=2)
result.push(parseInt(s.substr(i, 2), 10) + ".")
alert( result[2] ) // 3.
alert( result.join(" ") ) // 1. 2. 3. 99.

Categories

Resources