traverse a string char by char javascript - javascript

function SimpleSymbols(str) {
var letter =['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 newstr = "";
for (var i = 0; i<str.length; i++){
if (str.charAt(i).toLowerCase() in letter){
newstr += "M";
}
else{
newstr += "X";
}
}
return newstr;
}
If str is "Argument goes here" it returns XXXXXXXXX. WHy doesn't it return MMMMMMMMMM?

you do not look up an entry in an array with in. use indexOf() to find the position of an array entry. indexOf() will return the position or -1 if no entry is found.
for (var i = 0; i<str.length; i++){
var strChar = str.charAt(i).toLowerCase();
if ( letter.indexOf(strChar) >= 0 ) {
newstr += "M";
}
…

The in operator returns true if the object has a property with that name, not with that value.
An array is basically an object with numeric properties. I.e. the indexes are the property names of the object. It basically looks like this:
var letters = {
0: 'a',
1: 'b',
...
length: ...
};
So in your case the condition will only be true if str.charAt(i).toLowerCase() returns a number between 0 and letter.length (and since charAt only returns one character, it can only be 0-9).
Example:
> var letters = ['a', 'b', 'c'];
> 'a' in letters // array doesn't have a property 'a'
false
> 0 in letters // array has a property 0 (it's the first element)
true
So since, "Argument goes here" doesn't contain any digits, the in condition will always be false and that's why you get XXXXXX... as result.
See the question "How do I check if an array includes an object in JavaScript?" for testing the existence of an element in an array.
FWIW, to make the in operator work, you would have to create an object of the form:
var letters = {
'a': true,
'b': true,
// ...
};
but that's a bit cumbersome to write.

Allow me to offer a side view, another way handle what I think you intent to do by using Regular Expressions with something like:
"test2".replace(/[a-z]/gi,"M").replace(/[^M]/g,"X") //Outputs "MMMMX"
String.replace will replace an string that contains letters from [a-z] the i at the end of the expression means case insensitive. g means will search for all possible matches and not just the first match. In the second expression [^M] this ^ means negation so anything that is not an M will be replaced with X.
There is another way in which we implement a custom function within the String.replace using Regular Expressions and it can be implemented like this:
"test2".replace(/([a-z])|([^a-z])/gi,
function(m,g1, g2){
return g1 ? "M" : "X";
});
In regular expression parenthesis creates groups and | means or in this expression ([a-z])|([^a-z]) there 2 groups one with letters from a-z and the other which means everything that is not a-z with the replace function we asked only for group g1 if it is group 1 is M otherwise is an X.
Another cool thing you could do is add this function to all your string by prototyping it like:
String.prototype.traverse = function(){ return this.replace(/([a-z])|([^a-z])/gi,function(m,g1){ return g1 ? "M" : "X" });}
Then it can be used as simple as: "test1".traverse();

Related

Determine if string has any characters that aren't in a list of characters and if so, which characters don't match?

I'm working on a simple password validator and wondering if its possible in Regex or... anything besides individually checking for each character.
Basically if the user types in something like "aaaaaaaaa1aaaaa", I want to let the user know that the character "1" is not allowed (This is a super simple example).
I'm trying to avoid something like
if(value.indexOf('#') {}
if(value.indexOf('#') {}
if(value.indexOf('\') {}
Maybe something like:
if(/[^A-Za-z0-9]/.exec(value) {}
Any help?
If you just want to check if the string is valid, you can use RegExp.test() - this is more efficient that exec() as it will return true when it finds the first occurrence:
var value = "abc$de%f";
// checks if value contains any invalid character
if(/[^A-Za-z0-9]/.test(value)) {
alert('invalid');
}
If you want to pick out which characters are invalid you need to use String.match():
var value = "abc$de%f";
var invalidChars = value.match(/[^A-Za-z0-9]/g);
alert('The following characters are invalid: ' + invalidChars.join(''));
Although a simple loop can do the job, here's another approach using a lesser known Array.prototype.some method. From MDN's description of some:
The some() method tests whether some element in the array passes the test implemented by the provided function.
The advantage over looping is that it'll stop going through the array as soon as the test is positive, avoiding breaks.
var invalidChars = ['#', '#', '\\'];
var input = "test#";
function contains(e) {
return input.indexOf(e) > -1;
}
console.log(invalidChars.some(contains)); // true
I'd suggest:
function isValid (val) {
// a simple regular expression to express that the string must be, from start (^)
// to end ($) a sequence of one or more letters, a-z ([a-z]+), of upper-, or lower-,
// case (i):
var valid = /^[a-z]+$/i;
// returning a Boolean (true/false) of whether the passed-string matches the
// regular expression:
return valid.test(val);
}
console.log(isValid ('abcdef') ); // true
console.log(isValid ('abc1def') ); // false
Otherwise, to show the characters that are found in the string and not allowed:
function isValid(val) {
// caching the valid characters ([a-z]), which can be present multiple times in
// the string (g), and upper or lower case (i):
var valid = /[a-z]/gi;
// if replacing the valid characters with zero-length strings reduces the string to
// a length of zero (the assessment is true), then no invalid characters could
// be present and we return true; otherwise, if the evaluation is false
// we replace the valid characters by zero-length strings, then split the string
// between characters (split('')) to form an array and return that array:
return val.replace(valid, '').length === 0 ? true : val.replace(valid, '').split('');
}
console.log(isValid('abcdef')); // true
console.log(isValid('abc1de#f')); // ["1", "#"]
References:
JavaScript conditional operator (assessment ? ifTrue : ifFalse).
JavaScript Regular Expressions.
String.prototype.replace().
String.prototype.split().
RegExp.prototype.test().
If I understand what you are asking you could do the following:
function getInvalidChars() {
var badChars = {
'#' : true,
'/' : true,
'<' : true,
'>' : true
}
var invalidChars = [];
for (var i=0,x = inputString.length; i < x; i++) {
if (badChars[inputString[i]]) invalidChars.push(inputString[i]);
}
return invalidChars;
}
var inputString = 'im/b#d:strin>';
var badCharactersInString = getInvalidChars(inputString);
if (badCharactersInString.length) {
document.write("bad characters in string: " + badCharactersInString.join(','));
}

Trouble with Javascript easy coderbyte challenge

I'm attempting to answer this question:
Using the JavaScript language, have the function SimpleSymbols(str) take the str parameter being passed and determine if it is an acceptable sequence by either returning the string true or false. The str parameter will be composed of + and = symbols with several letters between them (ie. ++d+===+c++==a) and for the string to be true each letter must be surrounded by a + symbol. So the string to the left would be false. The string will not be empty and will have at least one letter.
Here's my solution:
function SimpleSymbols(str) {
var test;
for (var i =0; i<str.length; i++){
if ((str.charAt(i)!== '+' && str.charAt(i+1) === str.match(/[a-z]/))
||(str.charAt(i+1) === str.match(/[a-z]/) && str.charAt(i+2) !== '+')){
test = false;
break;
}
else if (str.charAt(0) === str.match(/[a-z]/)){
test = false;
break;}
else {
test= true;}
}
return test;
};
I think you can just use two regex and then compare the length of arrays returned by them
function SimpleSymbols(str){
return str.match(/[a-z]/g).length == str.match(/\+[a-z]\+/g).length;
}
The first regex /[a-z]/g will match all the letters and /\+[a-z]\+/g will match all the letters which are followed and preceded by a literal +.
Then, we just use the Array.length property to check if the lengths are same or not and then return the Boolean result. As simple as that.

When to use 'i' vs. 'str[i]'?

why does using 'i' in the if statement return different results than using 'str[i]'?
function ExOh(str) {
xCount = 0;
oCount = 0;
for (var i=0;i<str.length;i++){
if (str[i]=='x') {
xCount++;
} else if (str[i]=='o') {
oCount++;
}
}
if (xCount==oCount) {
return true;
} else {
return false;
}
}
console.log(ExOh("xox"));
i returns the current value of the same in the for loop: for (var i=0;i<str.length;i++)
And, str[i] returns the character in the string str at the i'th position.
So, although the value of i is the same inside the if or for loop, the actual values of i and str[i] will be different.
Readup:
for | MDN
array | MDN
In this case, i refers to the index of a character in the string str, and when you use str[i] you are accessing the character of str at index i. For example, take the following string:
var str = "My string";
The string str has 9 characters, and each index, from 0 to 8, will refer to a specific character within it. Thus, str[0] = "M", str[1] = "y", etc. Here, 0 and 1 are indexes, while "M" and "y" are characters at such indexes.
why does using 'i' in the if statement return different results than using 'str[i]'?
I in this case is an integer indicating the place (index) within an array. Where is str[i] is the item within that place.
i refers to the position or index of a character (beginning at 0), so in this case i refers to the index of a character in the string. It will return a number.
str[i] refers to the exact character of that string, not its position or index, so it will return a non-number, unless that character in the string happens to be a number.

traversing string in javascript

I have a number of strings concatenated together
"[thing 1,thing 2,cat in the hat,Dr. Suese]"
I would like to traverse this string to stop at a specific comma (given an index) and return the substring immediately after the comma and before the next comma. The problem is I need to do it in JavaScript. I assume it would be something like this
function returnSubstring(i,theString){
var j,k = 0;
while(theString.charCodeAt(k) != ','){
while(i > 0){
if (theString.charCodeAt(j) == ','){
i--;
}
j++;
}
k++;
}
return theString.substring(j,k);
}
Is this what it should look like or is there some syntax issue here
I would like to traverse this string to stop at a specific comma (given an index) and return the substring immediately after the comma and before the next comma.
--> Let's assume specific index for comma accpeted is 8 i.e. first comma index, you can do :
var givenCommaIndex = 8;
var value = "[thing 1,thing 2,cat in the hat,Dr. Suese]";
var subString = value.substring(givenCommaIndex+1, value.indexOf(",", givenCommaIndex+1));
console.log(subString);
// Output :
"thing 2"
I can write the reusable function like below, it will not just work for comma but other delimiters as well :
function getSubString(str, delimiter, indexOfDelimiter) {
// TODO : handle specific cases like str is undefined or delimiter is null
return str.substring(indexOfDelimiter+1, str.indexOf(delimiter, indexOfDelimiter+1));
}
You may split :
var token = "[thing 1,thing 2,cat in the hat,Dr. Suese]"
.slice(1,-1) // remove [ and ]
.split(',')
[2]; // the third token
Or use a regular expression :
var token = "[thing 1,thing 2,cat in the hat,Dr. Suese]"
.match(/([^\]\[,]+)/g)
[2];

cut out part of a string

Say, I have a string
"hello is it me you're looking for"
I want to cut part of this string out and return the new string, something like
s = string.cut(0,3);
s would now be equal to:
"lo is it me you're looking for"
EDIT: It may not be from 0 to 3. It could be from 5 to 7.
s = string.cut(5,7);
would return
"hellos it me you're looking for"
You're almost there. What you want is:
http://www.w3schools.com/jsref/jsref_substr.asp
So, in your example:
Var string = "hello is it me you're looking for";
s = string.substr(3);
As only providing a start (the first arg) takes from that index to the end of the string.
Update, how about something like:
function cut(str, cutStart, cutEnd){
return str.substr(0,cutStart) + str.substr(cutEnd+1);
}
Use
substring
function
Returns a subset of a string between
one index and another, or through the
end of the string.
substring(indexA, [indexB]);
indexA
An integer between 0 and one less than the length of the string.
indexB
(optional) An integer between 0 and the length of the string.
substring extracts characters from indexA up to but not including indexB. In particular:
* If indexA equals indexB, substring returns an empty string.
* If indexB is omitted, substring extracts characters to the end
of the string.
* If either argument is less than 0 or is NaN, it is treated as if
it were 0.
* If either argument is greater than stringName.length, it is treated as
if it were stringName.length.
If indexA is larger than indexB, then the effect of substring is as if the two arguments were swapped; for example, str.substring(1, 0) == str.substring(0, 1).
Some other more modern alternatives are:
Split and join
function cutFromString(oldStr, fullStr) {
return fullStr.split(oldStr).join('');
}
cutFromString('there ', 'Hello there world!'); // "Hello world!"
Adapted from MDN example
String.replace(), which uses regex. This means it can be more flexible with case sensitivity.
function cutFromString(oldStrRegex, fullStr) {
return fullStr.replace(oldStrRegex, '');
}
cutFromString(/there /i , 'Hello THERE world!'); // "Hello world!"
s = string.cut(5,7);
I'd prefer to do it as a separate function, but if you really want to be able to call it directly on a String from the prototype:
String.prototype.cut= function(i0, i1) {
return this.substring(0, i0)+this.substring(i1);
}
string.substring() is what you want.
Just as a reference for anyone looking for similar function, I have a String.prototype.bisect implementation that splits a string 3-ways using a regex/string delimiter and returns the before,delimiter-match and after parts of the string....
/*
Splits a string 3-ways along delimiter.
Delimiter can be a regex or a string.
Returns an array with [before,delimiter,after]
*/
String.prototype.bisect = function( delimiter){
var i,m,l=1;
if(typeof delimiter == 'string') i = this.indexOf(delimiter);
if(delimiter.exec){
m = this.match(delimiter);
i = m.index;
l = m[0].length
}
if(!i) i = this.length/2;
var res=[],temp;
if(temp = this.substring(0,i)) res.push(temp);
if(temp = this.substr(i,l)) res.push(temp);
if(temp = this.substring(i+l)) res.push(temp);
if(res.length == 3) return res;
return null;
};
/* though one could achieve similar and more optimal results for above with: */
"my string to split and get the before after splitting on and once".split(/and(.+)/,2)
// outputs => ["my string to split ", " get the before after splitting on and once"]
As stated here: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/String/split
If separator is a regular expression that contains capturing parentheses, then each time separator is matched the results (including any undefined results) of the capturing parentheses are spliced into the output array. However, not all browsers support this capability.
You need to do something like the following:
var s = "I am a string";
var sSubstring = s.substring(2); // sSubstring now equals "am a string".
You have two options about how to go about it:
http://www.quirksmode.org/js/strings.html#substring
http://www.quirksmode.org/js/strings.html#substr
Try the following:
var str="hello is it me you're looking for";
document.write(str.substring(3)+"<br />");
You can check this link
this works well
function stringCutter(str,cutCount,caretPos){
let firstPart = str.substring(0,caretPos-cutCount);
let secondPart = str.substring(caretPos,str.length);
return firstPart + secondPart;
}

Categories

Resources