Function to extract numbers only from a string - javascript

I have written a function that I want to take in a string and then return a string that contains only the number characters from the original string. It
function pureNumbers() {
var result;
for (var i = 0; i < phoneNumber.length; i++) {
if (Number(phoneNumber[i]) !== NaN) {
result ? result = result + phoneNumber[i] : result = phoneNumber[i]
}
}
return result;
}
pureNumbers('(123) 456-7890')
Desired result:
result: '1234567890'
What I actually get is:
result: 'undefined(123) 456-7890'
I know there's two issues here (possibly more).
The undefined at the beginning of my result is because my function is attempting to return the value of result in the first loop's iteration, before anything has been assigned to it. I set up the ternary conditional to cover this, not sure why it's not working...
My first if() conditional is intended to make the given character of the string be added to result only if it is a number, yet every single character is being added.
Any help appreciated - thanks in advance.

This gets all the numbers from a string as an array, then .join("") to join together the strings with no delimiter between them, I.e., a consecutive concatenation string of digit matches.
var numberPattern = /\d+/g;
'something102asdfkj1948948'.match( numberPattern ).join("");
Yields "1021948948"

The basic logic is below:
var x = 'Hello please call (727) 902-1112';
var numbers = x.match(/[0-9]/g).join('');
console.log(numbers);
Result: 7279021112
Now as to a function, I think this might help you:
var x = 'Hello please call';
var y = 'Hello please call (727) 902-1112';
function pureNumbers(param) {
result = param.match(/[0-9]/g);
if (Array.isArray(result)) {
return result.join('');
}
return false;
}
console.log(pureNumbers(x)); // returns false
console.log(pureNumbers(y)); // returns 7279021112
Note: isArray() does not work in older versions of IE 9. You would have to do it differently.

Your can also try the following: string.replace(/[^0-9]/g, ''); OR string.replace(/\D/g,''); to strip all the non-digit characters.
function pureNumbers(str) {
var num = str.replace(/[^0-9]/g, '');
return num;
}
alert(pureNumbers('(123) 456-7890'));

I only changed your function a little bit, though it can be solved in many ways, especially with regex.
function pureNumbers(phoneNumber) {
var result = "";
for (var i = 0; i < phoneNumber.length; i++) {
if (!isNaN(phoneNumber[i]) && phoneNumber[i].trim() !== '') {
result += phoneNumber[i];
}
}
return result;
}
Hope you may get some hint and improve for better solution.

Related

Creating a function that returns a function with individual letters [duplicate]

I would like to alert each letter of a string, but I am unsure how to do this.
So, if I have:
var str = 'This is my string';
I would like to be able to separately alert T, h, i, s, etc. This is just the beginning of an idea that I am working on, but I need to know how to process each letter separately.
I was thinking I might need to use the split function after testing what the length of the string is.
How can I do this?
If the order of alerts matters, use this:
for (var i = 0; i < str.length; i++) {
alert(str.charAt(i));
}
Or this: (see also this answer)
for (var i = 0; i < str.length; i++) {
alert(str[i]);
}
If the order of alerts doesn't matter, use this:
var i = str.length;
while (i--) {
alert(str.charAt(i));
}
Or this: (see also this answer)
var i = str.length;
while (i--) {
alert(str[i]);
}
var str = 'This is my string';
function matters() {
for (var i = 0; i < str.length; i++) {
alert(str.charAt(i));
}
}
function dontmatter() {
var i = str.length;
while (i--) {
alert(str.charAt(i));
}
}
<p>If the order of alerts matters, use this.</p>
<p>If the order of alerts doesn't matter, use this.</p>
It's probably more than solved. Just want to contribute with another simple solution:
var text = 'uololooo';
// With ES6
[...text].forEach(c => console.log(c))
// With the `of` operator
for (const c of text) {
console.log(c)
}
// With ES5
for (var x = 0, c=''; c = text.charAt(x); x++) {
console.log(c);
}
// ES5 without the for loop:
text.split('').forEach(function(c) {
console.log(c);
});
How to process each letter of text (with benchmarks)
https://jsperf.com/str-for-in-of-foreach-map-2
for
Classic and by far the one with the most performance. You should go with this one if you are planning to use it in a performance critical algorithm, or that it requires the maximum compatibility with browser versions.
for (var i = 0; i < str.length; i++) {
console.info(str[i]);
}
for...of
for...of is the new ES6 for iterator. Supported by most modern browsers. It is visually more appealing and is less prone to typing mistakes. If you are going for this one in a production application, you should be probably using a transpiler like Babel.
let result = '';
for (let letter of str) {
result += letter;
}
forEach
Functional approach. Airbnb approved. The biggest downside of doing it this way is the split(), that creates a new array to store each individual letter of the string.
Why? This enforces our immutable rule. Dealing with pure functions
that return values is easier to reason about than side effects.
// ES6 version.
let result = '';
str.split('').forEach(letter => {
result += letter;
});
or
var result = '';
str.split('').forEach(function(letter) {
result += letter;
});
The following are the ones I dislike.
for...in
Unlike for...of, you get the letter index instead of the letter. It performs pretty badly.
var result = '';
for (var letterIndex in str) {
result += str[letterIndex];
}
map
Function approach, which is good. However, map isn't meant to be used for that. It should be used when needing to change the values inside an array, which is not the case.
// ES6 version.
var result = '';
str.split('').map(letter => {
result += letter;
});
or
let result = '';
str.split('').map(function(letter) {
result += letter;
});
One possible solution in pure javascript:
for (var x = 0; x < str.length; x++)
{
var c = str.charAt(x);
alert(c);
}
Most if not all of the answers here are wrong because they will break whenever there is a character in the string outside the Unicode BMP (Basic Multilingual Plane). That means all Emoji will be broken.
JavaScript uses UTF-16 Unicode for all strings. In UTF-16, characters beyond the BMP are made out of two parts, called a "Surrogate Pair" and most of the answers here will process each part of such pairs individually instead of as a single character.
One way in modern JavaScript since at least 2016 is to use the new String iterator. Here's the example (almost) straight out of MDN:
var string = 'A\uD835\uDC68B\uD835\uDC69C\uD835\uDC6A';
for (var v of string) {
alert(v);
}
// "A"
// "\uD835\uDC68"
// "B"
// "\uD835\uDC69"
// "C"
// "\uD835\uDC6A"
You can try this
var arrValues = 'This is my string'.split('');
// Loop over each value in the array.
$.each(arrValues, function (intIndex, objValue) {
alert(objValue);
})
New JS allows this:
const str = 'This is my string';
Array.from(str).forEach(alert);
If you want to do a transformation on the text on a character level, and get the transformed text back at the end, you would do something like this:
var value = "alma";
var new_value = [...value].map((x) => x+"E").join("")
So the steps:
Split the string into an array (list) of characters
Map each character via a functor
Join the resulting array of chars together into the resulting string
NOTE: If you need performance, there are probably better, more optimized solutions for this. I posted this one as a clean codestyle approach.
One more solution...
var strg= 'This is my string';
for(indx in strg){
alert(strg[indx]);
}
It is better to use the for...of statement, if the string contains unicode characters, because of the different byte size.
for(var c of "tree 木") { console.log(c); }
//"𝐀A".length === 3
short answer: Array.from(string) will give you what you probably want and then you can iterate on it or whatever since it's just an array.
ok let's try it with this string: abc|⚫️\nβšͺ️|πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§.
codepoints are:
97
98
99
124
9899, 65039
10
9898, 65039
124
128104, 8205, 128105, 8205, 128103, 8205, 128103
so some characters have one codepoint (byte) and some have two or more, and a newline added for extra testing.
so after testing there are two ways:
byte per byte (codepoint per codepoint)
character groups (but not the whole family emoji)
string = "abc|⚫️\nβšͺ️|πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§"
console.log({ 'string': string }) // abc|⚫️\nβšͺ️|πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§
console.log({ 'string.length': string.length }) // 21
for (let i = 0; i < string.length; i += 1) {
console.log({ 'string[i]': string[i] }) // byte per byte
console.log({ 'string.charAt(i)': string.charAt(i) }) // byte per byte
}
for (let char of string) {
console.log({ 'for char of string': char }) // character groups
}
for (let char in string) {
console.log({ 'for char in string': char }) // index of byte per byte
}
string.replace(/./g, (char) => {
console.log({ 'string.replace(/./g, ...)': char }) // byte per byte
});
string.replace(/[\S\s]/g, (char) => {
console.log({ 'string.replace(/[\S\s]/g, ...)': char }) // byte per byte
});
[...string].forEach((char) => {
console.log({ "[...string].forEach": char }) // character groups
})
string.split('').forEach((char) => {
console.log({ "string.split('').forEach": char }) // byte per byte
})
Array.from(string).forEach((char) => {
console.log({ "Array.from(string).forEach": char }) // character groups
})
Array.prototype.map.call(string, (char) => {
console.log({ "Array.prototype.map.call(string, ...)": char }) // byte per byte
})
var regexp = /(?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g
string.replace(regexp, (char) => {
console.log({ 'str.replace(regexp, ...)': char }) // character groups
});
When I need to write short code or a one-liner, I use this "hack":
'Hello World'.replace(/./g, function (char) {
alert(char);
return char; // this is optional
});
This won't count newlines so that can be a good thing or a bad thing. If you which to include newlines, replace: /./ with /[\S\s]/. The other one-liners you may see probably use .split() which has many problems
You can now use in keyword.
var s = 'Alien';
for (var c in s) alert(s[c]);
You can now iterate over individual Unicode code points contained in a String by using String.prototype[##iterator], which returns a value of well known Symbol type Symbol.iterator - the default iterator for array-like Objects (String in this case).
Example code:
const str = 'The quick red 🦊 jumped over the lazy 🐢! ε€ͺ棒了!';
let iterator = str[Symbol.iterator]();
let theChar = iterator.next();
while(!theChar.done) {
console.log(theChar.value);
theChar = iterator.next();
}
// logs every unicode character as expected into the console.
This works with Unicode characters such as emoji or non-roman characters that would trip up legacy constructs.
Reference: MDN Link to String.prototype##iterator.
You can simply iterate it as in an array:
for(var i in txt){
console.log(txt[i]);
}
In ES6 / ES2015, you can iterate over an string with iterators,as you can see in
Symbol.iterator MDN
var str = 'Hello';
var it = str[Symbol.iterator]();
for (let v of it) {
console.log(v)
}
// "H"
// "e"
// "l"
// "l"
// "o"
It is a declarative style. What is the advantage? You do not have to concern about how to access each element of the string.
You can get an array of the individual characters like so
var test = "test string",
characters = test.split('');
and then loop using regular Javascript, or else you can iterate over the string's characters using jQuery by
var test = "test string";
$(test.split('')).each(function (index,character) {
alert(character);
});
// There are multiple ways but I find this easiest.
let str = 'This is my string';
for(let character of str)
console.log(character)
you can convert this string into an array of chars using split(), then iterate through it.
const str = "javascript";
const strArray = str.split('');
strArray.map(s => console.log(s));
In today's JavaScript you can
Array.prototype.map.call('This is my string', (c) => c+c)
Obviously, c+c represents whatever you want to do with c.
This returns
["TT", "hh", "ii", "ss", " ", "ii", "ss", " ",
"mm", "yy", " ", "ss", "tt", "rr", "ii", "nn", "gg"]
This should work in older browsers and with UTF-16 characters like πŸ’©.
This should be the most compatible solution. However, it is less performant than a for loop would be.
I generated the regular expression using regexpu
var str = 'My String πŸ’© ';
var regEx = /(?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g
str.replace(regEx, function (char) {
console.log(char)
});
Hope this helps!
You can access single characters with str.charAt(index) or str[index]. But the latter way is not part of ECMAScript so you better go with the former one.
If you want to animate each character you might need to wrap it in span element;
var $demoText = $("#demo-text");
$demoText.html( $demoText.html().replace(/./g, "<span>$&</span>").replace(/\s/g, " "));
I think this is the best way to do it, then process the spans. ( for example with TweenMax)
TweenMax.staggerFromTo( $demoText.find("span"), 0.2, {autoAlpha:0}, {autoAlpha:1}, 0.1 );
Try this code
function myFunction() {
var text =(document.getElementById("htext").value);
var meow = " <p> <,> </p>";
var i;
for (i = 0; i < 9000; i++) {
text+=text[i] ;
}
document.getElementById("demo2").innerHTML = text;
}
</script>
<p>Enter your text: <input type="text" id="htext"/>
<button onclick="myFunction();">click on me</button>
</p>

javascript program to check if a string is palindromes not returning false

I wrote this bit of code a a part of an exercise to check weather or not a string is palindromes. They program is working correctly in terms of checking the string but it does not return false when the string is not palindromes. What am I doing wrong? thanks
//convert the string to array
var stringArr = [ ];
var bool;
function palindrome(str) {
// make lowercase
var lowerCase = str.toLowerCase();
//remove numbers, special characters, and white spaces
var noNumbers = lowerCase.replace(/[0-9]/g, '');
var noSpecials = noNumbers.replace(/\W+/g, " ");
var finalString = noSpecials.replace(/\s/g, '');
stringArr = finalString.split("");
if (stringArr.sort(frontToBack)==stringArr.sort(backToFront)) {
bool = true;
}
else {
bool= false;
}
return bool;
}
function frontToBack (a,b) {return a-b;}
function backToFront (a,b) {return b-a;}
palindrome("eye");
if (stringArr.sort(frontToBack)==stringArr.sort(backToFront)) { is your problem.
In JavaScript, the sort method updates the value of the variable you are sorting. So in your comparison, once both sort's have run, both end up with the same value (since the second sort, effectively overrides the first).
For example.
var a = [1,7,3];
a.sort();
console.log(a); // will print 1,3,7
Edit: had a quick test, I think eavidan's suggestion is probably the best one.
Edit2: Just put together a quick version of a hopefully working palindrome function :)
function palindrome(str) { return str.split("").reverse().join("") == str;}
It is because string subtraction yields NaN, which means both sorted arrays are the same as the original.
Even if you did convert to ASCII coding, you sort the entire string, then for instance the string abba would be sorted front to back as aabb and back to front as bbaa. (edit: and also what Carl wrote about sort changing the original array. Still - sort is not the way to go here)
What you should do is just reverse the string (using reverse on the array) and compare.
You might do as follows;
var isPalindrome = s => { var t = s.toLowerCase()
.replace(/\s+/g,"");
return [].slice.call(t)
.reverse()
.every((b,i) => b === t[i]);
};
console.log(isPalindrome("Was it a car or a cat I saw"));
console.log(isPalindrome("This is not a palindrome"));
function pal()
{
var x=document.getElementById("a").value;
//input String
var y="";
//blank String
for (i=x.length-1;i>=0;i--)
//string run from backward
{
y=y+x[i];
//store string last to first one by one in blank string
}
if(x==y)
//compare blank and original string equal or not
{
console.log("Palindrome");
}
else
{
console.log("Not Palindrome ");
}
}

Failing test as a string

I am running through some exercises and run into this on codewars. Its a simple exercise with Instructions to create a function called shortcut to remove all the lowercase vowels in a given string.
Examples:
shortcut("codewars") // --> cdwrs
shortcut("goodbye") // --> gdby
I am newbie so I thought up this solution. but it doesn't work and I have no idea why
function shortcut(string){
// create an array of individual characters
var stage1 = string.split('');
// loop through array and remove the unneeded characters
for (i = string.length-1; i >= 0; i--) {
if (stage1[i] === "a"||
stage1[i] === "e"||
stage1[i] === "i"||
stage1[i] === "o"||
stage1[i] === "u") {
stage1.splice(i,1)
;}
};
// turn the array back into a string
string = stage1.join('');
return shortcut;
}
My gut is telling me that it will probably something to like split and join not creating "true" array's and strings.
I did it at first with a regex to make it a little more reusable but that was a nightmare. I would be happy to take suggestions on other methods of acheiving the same thing.
You are returning the function itself, instead of returning string
Using regex:
var str = 'codewars';
var regex = /[aeiou]/g;
var result = str.replace(regex, '');
document.write(result);
if interested in Regular Expression ;)
function shortcut(str) {
return str.replace(/[aeiou]/g, "");
}

In Javascript, how to find a character in a string and put all the characters before it in a variable

In javascript, I am trying to make a program that had to do with fractions that you can input and I need a function that will convert a fraction in this format( "10/27") to either 10 or 27 depending on user specification but I don't know how I would code this function. Any code or suggestions to get me started would be much appreciated.
You can search in string using indexOf(). It returns first position of searched string.
If you want to split string using a character in it, use split(). It will return an array. So for eg: in you string 27/10, indexOf / is 3 but if you do split, you will get array of 2 values, 27 and 10.
function splitString(str, searchStr) {
return str.split(searchStr);
}
function calculateValue(str) {
var searchStr = '/';
var values = splitString(str, searchStr);
var result = parseInt(values[0]) / parseInt(values[1]);
notify(str, result);
}
function notify(str, result) {
console.log(result);
document.getElementById("lblExpression").innerText = str;
document.getElementById("lblResult").innerText = result;
}
(function() {
var str = "27/10";
calculateValue(str)
})()
Expression:
<p id="lblExpression"></p>
Result:
<p id="lblResult"></p>
You can split the string into an array with split(), then take the first or second part as the numerator or denominator:
function getNumerator(fraction) {
// fraction = "10/27"
return fraction.split("/")[0];
}
function getDenominator(fraction) {
// fraction = "10/27"
return fraction.split("/")[1];
}
var fraction = "10/27".split("/");
var numerator = fraction[0];
var denominator = fraction[1];
You can of course use a library for it too: https://github.com/ekg/fraction.js
With this library the answer would be:
(new Fraction(10, 27)).numerator
Considering str contains the input value then,
a = str.substring(str.indexOf("/")+1);
b = str.substring(0, str.indexOf("/"));
Output:
if str is "10/17" then,
a == 17;
b == 10;

Splitting an array at only certain places but not others

I understand the .split() function quite well. But what I can seem to figure out is how to split in certain places but not in others. Sounds confusing? Well I mean for example, lets say I use .split(",") on the following string:
div:(li,div),div
Is it possible to split it so that only the commas ouside of the parentheses get split.
So the string above with the split method should return:
['div:(li,div)', 'div']
Of course at the moment it is also splitting the first comma inside of the parentheses, returning:
['div:(li', 'div)', 'div']
Is there some way to make this work like I desire?
If your expected strings are not going to become more complicated than this, you don't have to worry about writing code to parse them. Regex will work just fine.
http://jsfiddle.net/dC5HN/1/
var str = "div:(li,div),div:(li,div),div";
var parts = str.split(/,(?=(?:[^\)]|\([^\)]*\))*$)/g);
console.log(parts);
outputs:
["div:(li,div)", "div:(li,div)", "div"]
REGEX is not built for this sort of thing, which is essentially parsing.
When faced with this sort of situation previously I've first temporarily replaced the parenthesised parts with a placeholder, then split, then replaced the placeholders with the original parenthised parts.
A bit hacky, but it works:
var str = 'div:(li,div),div',
repls = [];
//first strip out parenthesised parts and store in array
str = str.replace(/\([^\)]*\)/g, function($0) {
repls.push($0);
return '*repl'+(repls.length - 1)+'*';
});
//with the parenthisised parts removed, split the string then iteratively
//reinstate the removed parenthisised parts
var pieces = str.split(',').map(function(val, index) {
return val.replace(/\*repl(\d+)\*/, function($0, $1) {
return repls[$1];
});
});
//test
console.log(pieces); //["div:(li,div)","div"]
This function will split whatever you specify in splitChar, but ignore that value if inside parenthesis:
function customSplit(stringToSplit, splitChar){
var arr = new Array();
var isParenOpen = 0
var curChar;
var curString = "";
for (var i = 0; i < stringToSplit.length; i++) {
curChar = stringToSplit.substr(i, 1);
switch(curChar) {
case "(":
isParenOpen++;
break;
case ")":
if(isParenOpen > 0) isParenOpen--;
break;
case splitChar:
if (isParenOpen < 1) {
arr.push(curString);
curString = "";
continue;
}
}
curString += curChar;
}
if (curString.length > 0) {
arr.push(curString);
}
return arr;
}

Categories