I want to change every other character (starting from the second) in my string to the value "K".
The variable name which I am using is shown to be "deprecated" in VS Code.
Here is my code:
let name = "mellow";
for (x = 0; name.length > x; x++) {
if (x % 2 != 0) {
name[x] = "K"
}
}
console.log(name);
First, you split the string to convert it into an array, with an empty separator. Then, you map its items (characters) to either themselves or K, depending on the result of `index % 2.
let input = "AAAAAAAAAAAAAAAA";
console.log(input.split("").map((item, index) => (index % 2 === 0) ? item : "K").join(""));
In JavaScript, strings are immutable. You can't update their values by indices. To make it work, you could build another string by concatenating characters to it. However, string concatenation is expensive.
Instead, we could push the required characters to an array and join them at the end.
let name = "mellow";
const result = [];
for (x = 0; name.length > x; x++) {
if (x % 2 != 0) {
result.push("K");
} else {
result.push(name[x]);
}
}
console.log(result.join(""));
The mentioned script could be written as the following as well.
let name = "mellow";
let result = [...name].map((char, index) => index % 2 !== 0 ? "K" : char).join("");
console.log(result);
Create a function that accepts a string as input, removes all content between parentheses, and returns the modified string. If the amount of left and right parentheses doesn't match, return empty string
I have to create a function that removes all content between parentheses and returns the string without it.
For example, this input 12(3(45))67(8)9 will return this output 12679.
If the number of parentheses isn't correct return an empty string.
This is my approach:
function removeContent(str) {
let leftP = 0, rightP = 0;
// wrong number of parentheses scenario
for( let i = 0; i < str.length; i++) {
if(str[i] === '(' ) leftP++;
if(str[i] === ')' ) rightP++;
}
if( leftP !== rightP) return "";
// remove the content otherwise
}
console.log(removeContent('12(3(45))67(8)9'));
Don't know how to do the combination between pairing parentheses and remove the content.
An easy way to do this is to keep track of bracket count, and then output letters only when the bracket count is equal to 0.
At the end, if the bracket count is not zero, you can also tell it to return the empty string as requested..
eg..
function removeContent(string) {
let bracketCount = 0;
let output = '';
for (const letter of string) {
if (letter === '(') bracketCount += 1
else if (letter === ')') bracketCount -= 1
else if (bracketCount === 0) output += letter;
}
return bracketCount === 0 ? output : '';
}
console.log(removeContent('12(3(45))67(8)9'));
console.log(removeContent('12(345))67(8)9'));
console.log(removeContent('1(2)(3)45(7)8(((9)))77'));
do a find replace with regular expression /\(+[\d\(]*\)+/g
I am trying to solve some JS problem. I want to check if an IP address is a valid one.
So the numbers must be between 0-255.
So what I want to do at this point, is to get an IP ex 192.168.1.1 and get substrings and load them to an array, so I want to create an array that looks like that:
array = ['192' , '168' , '1' , '1'];
I've tried various approaches in my algorithm but can't manage to target dynamically the numbers and split them between every dot.
I've done several tries, and thats the closest I could get.
let str = '192.168.1.1';
isValidIp(str);
function isValidIP(str) {
let array = [];
let substringArray = [];
for (let i=0; i<str.length; i++){
if (str[i] == '.') array.push(i);
}
let counter = 0;
for (let i in array){
substringArray.push(str.substring(counter, array[i]));
counter = array[i];
}
console.log(substringArray);
}
Which returns:
[ '192', '.168', '.1' ]
You can use the split() function of JavaScript which returns an array of every element separated by the digit specified. Or, which I wouldn't recommend, you could use RegEx. Here is an example of both:
function isValidIPwRegEx(str){
if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(str))
{
return true;
}
return false;
}
function isValidIP(str) {
let array = str.split("."),
isIP = true;
array = array.filter( block => !block.includes("+") && !block.includes("e") );
if(array.length!=4) return false;
array.forEach((number) => {
if ( !(+number >=0 && +number <= 255) ) { //As #p.s.w.g kindly suggested
isIP = false;
}
});
return isIP;
}
//With RegEx
console.log("With RegEx");
console.log(isValidIPwRegEx("192.168.1.1"));
console.log(isValidIPwRegEx("blah.blah.blah.blah")); //As #georg suggested
console.log(isValidIPwRegEx("1e1.2e1.+3e1.+5e1")); //As #georg again suggested to #Nina Scholz
console.log("");
//Without RegEx
console.log("Without RegEx");
console.log(isValidIP("192.168.1.1"));
console.log(isValidIP("blah.blah.blah.blah")); //As #georg suggested
console.log(isValidIP("1e1.2e1.+3e1.+5e1")); //As #georg again suggested to #Nina Scholz
console.log(isValidIP("1e1.2e1.3e1.5e1"));
Use String's split function.
So, something like "192.168.1.1".split(".")
You could split the string and check if the length is four and all values are integers and smaller than 256.
var ip = '192.168.1.1',
values = ip.split('.'),
valid = values.length === 4 && values.every(v => +v >= 0 && +v < 256);
console.log(values);
console.log(valid);
function isValidIP(str) {
let re = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
let m = str.match(re);
return m &&
m[1] >= 0 && m[1] <= 255 &&
m[2] >= 0 && m[2] <= 255 &&
m[3] >= 0 && m[3] <= 255 &&
m[4] >= 0 && m[4] <= 255
;
}
If you wish to be more precise, each digit check can be:
(0|[1-9]\d{0:2})
This prevents extraneous leading 0's.
I am implementing password complexity checks, one of the requirement is that the password contain at least one of a set of chars.
How would I code an efficient function for that, ie
function hasOneOfChars(s, chars) {
// assuming both s and chars are strings,
// return true iff s has at least one char from chars
}
Thanks!
Instead of using above function Try using it with regex pattern.
Contain at least 8 characters
contain at least 1 number
contain at least 1 lowercase character (a-z)
contain at least 1 uppercase character (A-Z)
contains only 0-9a-zA-Z
if you want set of chars use below pattern, Moreover {4,} is atleast contain charaters so you can change according to your requirement
[a-zA-Z0-9]{4,}
Thanks.
By requirement to receive 2 strings arguments. You can try the following code.
function hasOneOfChars(s, chars) {
for (let char of chars.split(""))
if (s.indexOf(char) > -1) {
return true;
}
return false;
}
console.log(hasOneOfChars("abcd", "abcasjkdf"));
You could sort both strings and do the following :
var s = "ytreza".split("").sort().join("");
var chars = "ytrewq".split("").sort().join("");
hasOneOfChars(s, chars); // true
function hasOneOfChars (s, chars) {
var a, b, i, n;
if (s < chars) a = s, b = chars;
else a = chars, b = s;
i = 0, n = a.length;
while (i < n && a[i] !== b[0]) i++;
return i < n;
}
Using sorted strings you don't have to loop through both strings anymore :
a = "azerty"
b = "qwerty"
n = a.length // 6
i = 0, a[i] === b[0] ? false
i = 1, a[i] === b[0] ? false
i = 2, a[i] === b[0] ? true
return i < n // true
(credit goes to CertainPerformance)
// assuming both s and chars are strings, return true iff s has at least one char from chars
function hasOneOfChars(s, chars) {
return [...chars].some(char => s.includes(char));
}
console.log(hasOneOfChars('aaabbb', 'ax'));
console.log(hasOneOfChars('aaabbb', 'xy'));
I would like to sort an array of strings (in JavaScript) such that groups of digits within the strings are compared as integers not strings. I am not worried about signed or floating point numbers.
For example, the result should be ["a1b3","a9b2","a10b2","a10b11"] not ["a1b3","a10b11","a10b2","a9b2"]
The easiest way to do this seems to be splitting each string on boundaries around groups of digits. Is there a pattern I can pass to String.split to split on character boundaries without removing any characters?
"abc11def22ghi".split(/?/) = ["abc","11","def","22","ghi"];
Or is there another way to compare strings that does not involve splitting them up, perhaps by padding all groups of digits with leading zeros so they are the same length?
"aa1bb" => "aa00000001bb", "aa10bb" => "aa00000010bb"
I am working with arbitrary strings, not strings that have a specific arrangement of digit groups.
I like the /(\d+)/ one liner from Gaby to split the array. How backwards compatible is that?
The solutions that parse the strings once in a way that can be used to rebuild the originals are much more efficient that this compare function. None of the answers handle some strings starting with digits and others not, but that would be easy enough to remedy and was not explicit in the original question.
["a100", "a20", "a3", "a3b", "a3b100", "a3b20", "a3b3", "!!", "~~", "9", "10", "9.5"].sort(function (inA, inB) {
var result = 0;
var a, b, pattern = /(\d+)/;
var as = inA.split(pattern);
var bs = inB.split(pattern);
var index, count = as.length;
if (('' === as[0]) === ('' === bs[0])) {
if (count > bs.length)
count = bs.length;
for (index = 0; index < count && 0 === result; ++index) {
a = as[index]; b = bs[index];
if (index & 1) {
result = a - b;
} else {
result = !(a < b) ? (a > b) ? 1 : 0 : -1;
}
}
if (0 === result)
result = as.length - bs.length;
} else {
result = !(inA < inB) ? (inA > inB) ? 1 : 0 : -1;
}
return result;
}).toString();
Result: "!!,9,9.5,10,a3,a3b,a3b3,a3b20,a3b100,a20,a100,~~"
Another variant is to use an instance of Intl.Collator with the numeric option:
var array = ["a100", "a20", "a3", "a3b", "a3b100", "a3b20", "a3b3", "!!", "~~", "9", "10", "9.5"];
var collator = new Intl.Collator([], {numeric: true});
array.sort((a, b) => collator.compare(a, b));
console.log(array);
I think this does what you want
function sortArray(arr) {
var tempArr = [], n;
for (var i in arr) {
tempArr[i] = arr[i].match(/([^0-9]+)|([0-9]+)/g);
for (var j in tempArr[i]) {
if( ! isNaN(n = parseInt(tempArr[i][j])) ){
tempArr[i][j] = n;
}
}
}
tempArr.sort(function (x, y) {
for (var i in x) {
if (y.length < i || x[i] < y[i]) {
return -1; // x is longer
}
if (x[i] > y[i]) {
return 1;
}
}
return 0;
});
for (var i in tempArr) {
arr[i] = tempArr[i].join('');
}
return arr;
}
alert(
sortArray(["a1b3", "a10b11", "a10b2", "a9b2"]).join(",")
);
Assuming you want to just do a numeric sort by the digits in each array entry (ignoring the non-digits), you can use this:
function sortByDigits(array) {
var re = /\D/g;
array.sort(function(a, b) {
return(parseInt(a.replace(re, ""), 10) - parseInt(b.replace(re, ""), 10));
});
return(array);
}
It uses a custom sort function that removes the digits and converts to a number each time it's asked to do a comparison. You can see it work here: http://jsfiddle.net/jfriend00/t87m2/.
Use this compare function for sorting...
function compareLists(a, b) {
var alist = a.split(/(\d+)/), // Split text on change from anything
// to digit and digit to anything
blist = b.split(/(\d+)/); // Split text on change from anything
// to digit and digit to anything
alist.slice(-1) == '' ? alist.pop() : null; // Remove the last element if empty
blist.slice(-1) == '' ? blist.pop() : null; // Remove the last element if empty
for (var i = 0, len = alist.length; i < len; i++) {
if (alist[i] != blist[i]){ // Find the first non-equal part
if (alist[i].match(/\d/)) // If numeric
{
return +alist[i] - +blist[i]; // Compare as number
} else {
return alist[i].localeCompare(blist[i]); // Compare as string
}
}
}
return true;
}
Syntax
var data = ["a1b3", "a10b11", "b10b2", "a9b2", "a1b20", "a1c4"];
data.sort(compareLists);
alert(data);
There is a demo at http://jsfiddle.net/h9Rqr/7/.
Here's a more complete solution that sorts according to both letters and numbers in the strings
function sort(list) {
var i, l, mi, ml, x;
// copy the original array
list = list.slice(0);
// split the strings, converting numeric (integer) parts to integers
// and leaving letters as strings
for( i = 0, l = list.length; i < l; i++ ) {
list[i] = list[i].match(/(\d+|[a-z]+)/g);
for( mi = 0, ml = list[i].length; mi < ml ; mi++ ) {
x = parseInt(list[i][mi], 10);
list[i][mi] = !!x || x === 0 ? x : list[i][mi];
}
}
// sort deeply, without comparing integers as strings
list = list.sort(function(a, b) {
var i = 0, l = a.length, res = 0;
while( res === 0 && i < l) {
if( a[i] !== b[i] ) {
res = a[i] < b[i] ? -1 : 1;
break;
}
// If you want to ignore the letters, and only sort by numbers
// use this instead:
//
// if( typeof a[i] === "number" && a[i] !== b[i] ) {
// res = a[i] < b[i] ? -1 : 1;
// break;
// }
i++;
}
return res;
});
// glue it together again
for( i = 0, l = list.length; i < l; i++ ) {
list[i] = list[i].join("");
}
return list;
}
I needed a way to take a mixed string and create a string that could be sorted elsewhere, so that numbers sorted numerically and letters alphabetically. Based on answers above I created the following, which pads out all numbers in a way I can understand, wherever they appear in the string.
function padAllNumbers(strIn) {
// Used to create mixed strings that sort numerically as well as non-numerically
var patternDigits = /(\d+)/g; // This recognises digit/non-digit boundaries
var astrIn = strIn.split( patternDigits ); // we create an array of alternating digit/non-digit groups
var result = "";
for (var i=0;i<astrIn.length; i++) {
if (astrIn[i] != "") { // first and last elements can be "" and we don't want these padded out
if (isNaN(astrIn[i])) {
result += astrIn[i];
} else {
result += padOneNumberString("000000000",astrIn[i]);
}
}
}
return result;
}
function padOneNumberString(pad,strNum,left) {
// Pad out a string at left (or right)
if (typeof strNum === "undefined") return pad;
if (typeof left === "undefined") left = true;
var padLen = pad.length - (""+ strNum).length;
var padding = pad.substr(0,padLen);
return left? padding + strNum : strNum + padding;
}
Sorting occurs from left to right unless you create a custom algorithm. Letters or digits are compared digits first and then letters.
However, what you want to accomplish as per your own example (a1, a9, a10) won’t ever happen. That would require you knowing the data beforehand and splitting the string in every possible way before applying the sorting.
One final alternative would be:
a) break each and every string from left to right whenever there is a change from letter to digit and vice versa; &
b) then start the sorting on those groups from right-to-left. That will be a very demanding algorithm. Can be done!
Finally, if you are the generator of the original "text", you should consider NORMALIZING the output where a1 a9 a10 could be outputted as a01 a09 a10. This way you could have full control of the final version of the algorithm.