Regex match after delimiter and find higher number of the match? - javascript

I have a match equation
function start() {
var str = "10x2+10x+10y100-20y30";
var match = str.match(/([a-z])=?(\d+)/g);//find the higher value of power only and also print the power value only withput alphapets).i need match like "100"
var text;
if(match < 10)
{text = "less 10";}
else if(match == "10")
{text == "equal";}
else
{text ="above 10";}
document.getElementById('demo').innerHTML=text;
}
start();
<p id="demo"></p>
i need match the power values and also getting out with higher power value only.
example :10x2+10y90+9x91 out --> "90".
what wrong with my and corret my regex match with suitable format.Thank You

The variable match contains all the powers that matches your regex, not just one. You'll have to iterate over them to find the greatest.
I took your code and modified it a bit to work :
function start() {
var str = "10x2+10x+10y100-20y30";
var match = str.match(/([a-z])=?(\d+)/g);//find the higher value of power only and also print the power value only withput alphapets).i need match like "100"
var max = 0;
for (var i = 0; i < match.length; i++) { // Iterate over all matches
var currentValue = parseInt(match[i].substring(1)); // Get the value of that match, without using the first letter
if (currentValue > max) {
max = currentValue; // Update maximum if it is greater than the old one
}
}
document.getElementById('demo').innerHTML=max;
}
start();
<p id="demo"></p>

Try this:
const str = '10x2+10x+10y100-20y30'
,regex = /([a-z])=?(\d+)/g
const matches = []
let match
while ((match = regex.exec(str)) !== null) {
matches.push(match[2])
}
const result = matches.reduce((a, b) => Number(a) > Number(b) ? a : b)
console.log(result)

Related

Why does this embedded function not work (inside of a javascript algorithm), and thereby preventing the javascript algorithm from being solved?

Question
Find the longest substring in alphabetical order.
Example: the longest alphabetical substring in "asdfaaaabbbbcttavvfffffdf" is "aaaabbbbctt".
There are tests with strings up to 10 000 characters long so your code will need to be efficient.
The input will only consist of lowercase characters and will be at least one letter long.
If there are multiple solutions, return the one that appears first.
My Solution
function longest(str) {
//first element of count == total count of the highest number
//second element of count == longest str so far
let count = [0, ''];
//temp count == length of current str
let tempCount = [0];
//split the str to an array
let strArr = str.split('');
//loop through each letter of the string
for(let i = 0; i < strArr.length; i++){
//if the character is higher in the alpahabet than the last then
if(convertToNumber(strArr[i])<convertToNumber((strArr[i]-1)) || convertToNumber((strArr[i]-1))== undefined){
tempCount[0]++;
//if the current character is not higher than the last
} else {
if(tempCount[0] > count[0]){
//change the longest str number to the length of this str
count[0] = tempCount[0];
//slice the new longest str
let longestStr = strArr.slice(strArr[i]-tempCount[0], strArr[i]);
//join the str together
count[1] = longestStr.join('');
//reset the temp count
tempCount[0] = 0;
} else {
//reset the temp count
tempCount[0] = 0;
}
}
}
//converts the relevant letter to a code
function convertToNumber(letter){
return letter.charCodeAt(0);
}
//returns the longest str
return count[1];
}
console.log(longest('asdfaaaabbbbcttavvfffffdf'));
The algorithm returns 'letter.charCodeAt is not a function'
Why is this the case and how can I make adjustments to fix the algorithm?
The problem is in here:
if(convertToNumber(strArr[i])<convertToNumber((strArr[i]-1)) || convertToNumber((strArr[i]-1))== undefined)
you are trying to subtract 1(Number) from a letter(String). It should be strArr[i-1].
But also
even after fixing it you'd still get an error for:
convertToNumber(strArr[i]) < convertToNumber(strArr[i-1])
if i will be zero as strArr[-1] will give undefined.
const arr = [1, 2, 3];
console.log(arr[-1]);
Is basically undefined.charCodeAt(0);, which will produce error.
I know that the OP wants a solution for his error. fedsec showed him for this a way. So I think there is nothing else to do.
I just put here my solution of the task, so the OP can compare to other possible solutions.
function longest(str) {
let max = 1;
let maxStr = str.charAt(0);
let char = maxStr;
let testStr = maxStr;
let count = 1;
for (i=1; i<=str.length; i++) {
let prev = char;
char = str.charAt(i);
if (prev <= char) {
count++;
testStr += char;
if (count>max) {
max = count;
maxStr = testStr;
}
} else {
if ( i+count >str.length) break;
count = 1;
testStr = char;
}
}
return(maxStr);
}
console.log(longest('asdfaaaabbbbcttavvfffffdf'));

How to move all capital letters to the beginning of the string?

I've been practicing simple solutions using what I've been learning / known.
The question I've faced is, how to move the capital letters in the string to the front?
I've solved it, but it's not to my expectation as my original idea was to → find the uppercase letter → put them in an array → concat the uppercase with the original string array with the uppercase letter removed in it.
Hence my question is, how can I remove the capital letter in the first conditional statement so I won't need to create another conditional statement to find the lower case and store the lower case letter in an array?
For example, the input string is 'heLLo' → output would be 'LLheo' (the capital letters are now in front).
Thank you!
function capToFront(s) {
var sp = s.split("");
var caps = [];
var lower = []
for (var i = 0; i < sp.length; i++)
{
if (sp[i] == sp[i].toUpperCase()){
caps.push(sp[i]);
**//How can i remove the capital letter in "sp" array as I've pushed them into the caps Array**
}
if (sp[i] == sp[i].toLowerCase()){
lower.push(sp[i]);
}
}
return caps.join("").concat(lower.join(""));
}
With RegExp, you can accomplish your goal in one line without any loops:
const result = [...'heLLo'].sort(l => /[A-Z]/.test(l) ? -1 : 0).join('');
console.log(result); // LLheo
If you want to ensure the original order among the capital letters is preserved, it will be slightly longer:
const result = [...'Hello World Foo Bar']
.sort((a, b) => /[A-Z]/.test(a) ? /[A-Z]/.test(b) ? 0 : -1 : 0)
.join('');
console.log(result); // HWFBello orld oo ar
You can reach your goal with a smaller loop by using Regex.
function capToFront(sp) {
let upperRgx = /[A-Z]/g;
let upperLetters = sp.match(upperRgx);
for(let i=0; i < upperLetters.length;i++) {
let indx = sp.indexOf(upperLetters[i]);
sp = sp.substring(0,indx)+sp.substring(indx+1,sp.length);
}
sp = upperLetters.join("")+sp;
return sp;
}
console.log(capToFront("heLLo")) // Output: LLheo
Use the Splice method to remove.
function capToFront(s) {
var sp = s.split("");
var caps = [];
var lower = []
for (var i = 0; i < sp.length; i++)
{
if (sp[i] == sp[i].toUpperCase()){
caps.push(sp[i]);
// Use the `splice` method to remove
sp.splice(i, 1);
}
if (sp[i] == sp[i].toLowerCase()){
lower.push(sp[i]);
}
}
console.log('sp', sp);
return caps.join("").concat(lower.join(""));
}
console.log(capToFront("stAck"))
You can also try this approach where you check the ASCII value of characters as the capital letters lie between 65 and 90 then use .sort and .join methods on the array accordingly
function capToFront(s) {
var sp = s.split("");
const res = sp.sort((a,b)=> isCaps(a) ? isCaps(b) ? 0 : -1 : 0)
return res.join("")
}
function isCaps(c){
return c.charCodeAt()>=65 && c.charCodeAt()<=90
}
console.log(capToFront('hIsAmplEStRing'))

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 do you sort letters in JavaScript, with capital and lowercase letters combined?

I'm working on a JavaScript (jQuery's OK too if this needs it, but I doubt it will) function to alphabetize a string of letters. Let's say the string that I want to sort is: "ACBacb".
My code as of now is this:
var string='ACBacb';
alert(string.split('').sort().join(''));
This returns ABCabc. I can see why that happens, but that is not the format that I am looking for. Is there a way that I can sort it by putting the same letters next to each other, capital letter first? So when I put in ACBacb, I get AaBbCc?
Array.sort can have a sort function as optional argument.
What about sorting the string first (ACBacbA becomes AABCabc), and then sorting it case-insensitive:
function case_insensitive_comp(strA, strB) {
return strA.toLowerCase().localeCompare(strB.toLowerCase());
}
var str = 'ACBacbA';
// split the string in chunks
str = str.split("");
// sorting
str = str.sort();
str = str.sort( case_insensitive_comp )
// concatenate the chunks in one string
str = str.join("");
alert(str);
As per Felix suggestion, the first sort function can be omitted and merged in the second one. First, do a case-insensitive comparison between both characters. If they are equal, check their case-sensitive equivalents. Return -1 or 1 for a difference and zero for equality.
function compare(strA, strB) {
var icmp = strA.toLowerCase().localeCompare(strB.toLowerCase());
if (icmp != 0) {
// spotted a difference when considering the locale
return icmp;
}
// no difference found when considering locale, let's see whether
// capitalization matters
if (strA > strB) {
return 1;
} else if (strA < strB) {
return -1;
} else {
// the characters are equal.
return 0;
}
}
var str = 'ACBacbA';
str = str.split('');
str = str.sort( compare );
str = str.join('');
You can pass a custom comparison function to Array.sort()
The already given answers are right so far that you have to use a custom comparison function. However you have to add an extra step to sort capital letters before lower case once:
function cmp(x,y) {
if(x.toLowerCase() !== y.toLowerCase()) {
x = x.toLowerCase();
y = y.toLowerCase();
}
return x > y ? 1 : (x < y ? -1 : 0);
// or
// return x.localeCompare(y);
}
If the letters are the same, the originals have to be compared, not the lower case versions. The upper case letter is always "larger" than the lower case version.
DEMO (based on #Matt Ball's version)
a working example http://jsfiddle.net/uGwZ3/
var string='ACBacb';
alert(string.split('').sort(caseInsensitiveSort).join(''));
function caseInsensitiveSort(a, b)
{
var ret = 0;
a = a.toLowerCase();b = b.toLowerCase();
if(a > b)
ret = 1;
if(a < b)
ret = -1;
return ret;
}
Use a custom sort function like this:
function customSortfunc(a,b){
var lca = a.toLowerCase(), lcb = b.toLowerCase();
return lca > lcb ? 1 : lca < lcb ? -1 : 0;
}
var string='ACBacb';
alert(string.split('').sort(customSortfunc).join(''));
You can read more about the sort function here: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort
Beware: if you use localeCompare like other answer suggests "u" and "ü" will be sorted together as the same letter, since it disregards all diacritics.
basic example for another replace, combined with lowercase :D
<button onclick="myFunction('U')">Try it</button>
<p id="demo"></p>
<script>
function myFunction(val) {
var str = "HELLO WORLD!";
var res = str.toLowerCase().split("o");
var elem = document.getElementById("demo").innerHTML
for(i = 0; i < res.length; i++){
(i > 0)?elem += val + res[i]:elem += res[i];
}
}
</script>

how to parse string to int in javascript

i want int from string in javascript how i can get them from
test1 , stsfdf233, fdfk323,
are anyone show me the method to get the integer from this string.
it is a rule that int is always in the back of the string.
how i can get the int who was at last in my string
var s = 'abc123';
var number = s.match(/\d+$/);
number = parseInt(number, 10);
The first step is a simple regular expression - \d+$ will match the digits near the end.
On the next step, we use parseInt on the string we've matched before, to get a proper number.
You can use a regex to extract the numbers in the string via String#match, and convert each of them to a number via parseInt:
var str, matches, index, num;
str = "test123and456";
matches = str.match(/\d+/g);
for (index = 0; index < matches.length; ++index) {
num = parseInt(matches[index], 10);
display("Digit series #" + index + " converts to " + num);
}
Live Example
If the numbers really occur only at the ends of the strings or you just want to convert the first set of digits you find, you can simplify a bit:
var str, matches, num;
str = "test123";
matches = str.match(/\d+/);
if (matches) {
num = parseInt(matches[0], 10);
display("Found match, converts to: " + num);
}
else {
display("No digits found");
}
Live example
If you want to ignore digits that aren't at the end, add $ to the end of the regex:
matches = str.match(/\d+$/);
Live example
var str = "stsfdf233";
var num = parseInt(str.replace(/\D/g, ''), 10);
var match = "stsfdf233".match(/\d+$/);
var result = 0; // default value
if(match != null) {
result = parseInt(match[0], 10);
}
Yet another alternative, this time without any replace or Regular Expression, just one simple loop:
function ExtractInteger(sValue)
{
var sDigits = "";
for (var i = sValue.length - 1; i >= 0; i--)
{
var c = sValue.charAt(i);
if (c < "0" || c > "9")
break;
sDigits = c + sDigits;
}
return (sDigits.length > 0) ? parseInt(sDigits, 10) : NaN;
}
Usage example:
var s = "stsfdf233";
var n = ExtractInteger(s);
alert(n);
This might help you
var str = 'abc123';
var number = str.match(/\d/g).join("");
Use my extension to String class :
String.prototype.toInt=function(){
return parseInt(this.replace(/\D/g, ''),10);
}
Then :
"ddfdsf121iu".toInt();
Will return an integer : 121
First positive or negative number:
"foo-22bar11".match(/-?\d+/); // -22
javascript:alert('stsfdf233'.match(/\d+$/)[0])
Global.parseInt with radix is overkill here, regexp extracted decimal digits already and rigth trimmed string

Categories

Resources