How we can code the case insensitive in JavaScript? - javascript

In my project I need to take care about the case insensitive, and I don't know how can I code something like that in JavaScript.
If I write on my terminal, I need for my code to understand the same thing :
`BOB
bob
Bob`
My code :
#!/usr/bin/env node
let chunk = "";
process.stdin.on("data", data => {
chunk += data.toString();
});
process.stdin.on("end", () => {
chunk.replace(/^\s*[\r\n]/gm,"").split(/\s+/).ignoreCase.forEach(function (s) {
process.stdout.write(
s === 'bob'
? 'boy \n'
: s === 'alicia'
? 'girl\n'
: s === 'cookie'
? 'dog \n'
: 'unknown \n');
});
});
The result I need to display is :
`boy
boy
boy`
I tried to do it with ignoreCase but it does not work, can you explain me why please?

Simply use String.prototype.toLowerCase on all your strings on input so that when you compare them there is only one way they can be represented.
process.stdin.on("data", data => {
chunk += data.toString().toLowerCase();
});

Just take the input and force it to all lower or upper case with String.toLowerCase() or String.toUpperCase() and then compare it to the same cased string:
console.log("test" === "Test"); // false
console.log("test" === "Test".toLowerCase()); // true
console.log("TeSt".toUpperCase() === "Test".toUpperCase()); // true

The RegExp.prototype.ignorecase property holds a boolean value for whether the the "i" flag is set for a regular expression. This is not a function and does not provide any manipulation operation to the expression or string.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase
What you may want to consider doing is calling something like the String.prototype.toLowerCase() function which will convert the string to lower case.
Edit: if it helps, I think you might place the toLowerCase() before the split(), since toLowerCase() is the String's function, not an array's function. And unless you want to later call it separately on each string, might be fastest to do it in one place, something like this:
chunk.replace(/^\s*[\r\n]/gm,"").toLowerCase().split(/\s+/).forEach(function (s) {
// function here
});

Related

Javascript find and match last item of the string

I am trying tor write this function that Check if a string (first argument, str) ends with the given target string (second argument, target). I have used this code but it seems not to work. How can i tweak it?
function confirmEnding(str, target) {
var last = str.substring(-1);
var last2 = target.substring(-1);
if (last == last2) return true;
else if (last !== last2) return false;
}
confirmEnding("Walking on water and developing software from a specification
are easy if both are frozen", "specification") )/*should return "false".
confirmEnding("Bastian", "n") should return true.
confirmEnding("Connor", "n") should return false.
confirmEnding("Walking on water and developing software from a specification
are easy if both are frozen", "specification") should return false.
confirmEnding("He has to give me a new name", "name") should return true.
confirmEnding("Open sesame", "same") should return true.
confirmEnding("Open sesame", "pen") should return false.
confirmEnding("If you want to save our world, you must hurry. We dont know
how much longer we can withstand the nothing", "mountain") should return
false.
Do not use the built-in method .endsWith() to solve the challenge.*/
In order to pass all of the tests with the desired return values, the function should not be comparing the last character of the string, but rather the entire string, target to the corresponding end substring of str. You need the length of target to find the correct starting index for the corresponding substring in str as follows:
function confirmEnding (str, target) {
return str.substr(-(target.length)) === target
}
Your code is comparing the entire strings. See substring() documentation below. -1 is defaulting to 0 thus returning the substring starting at index 0 and returning the rest of the string (the entire string) since no end index is given. .
"If either argument is less than 0 or is NaN, it is treated as if it
were 0."
You can use the substr() method instead of substring() if you want to use negative indices. substr() recognizes negative index values instead of defaulting to 0.
"If start is negative, substr() uses it as a character index from the
end of the string."
You can use the length of target and subtract it from the length of str to get the correct substring for comparison. This will return all of the characters from this index to the end of the string as in str.length - target.lengththough you only really need target.length to make the comparison using negative indices.
Using substring():
function confirmEnding (str, target) {
var last = str.substring(str.length-(target.length));
if (last == target ) return true;
else return false;
}
Using substr():
function confirmEnding (str, target) {
var last = str.substr(-(target.length));
if (last == target ) return true;
else return false;
}
or a cleaner/alternate implementation:
function confirmEnding (str, target) {
return str.substr(-(target.length) === target)
}
substr() documentation
substring() documentation
After seeing the ongoing confusion over this case (abbreviated for readability):
confirmEnding(
"Walking on water...both are frozen",
"specification"
); // Should return false (why not true?)
and also this interesting note:
/* Do not use the built-in method .endsWith() to solve the challenge. */
I have a hunch about what may have happened.
Double-check the instructions for this question. Are you sure you're supposed to test if the last character of each string is the same? It sounds like you are supposed to test if the src string ends with the entire target string.
After all, that is what the .endsWith() method does. And it explains the mystery of the test case above.
The MDN documentation for .endsWith() doesn't describe the method very well, but the examples it gives make it clear.
With that understanding, you can probably now write the code. I'm not going to write it for you, but I will drop some hints below. I added some code for your tests so that they not only log the result, but also whether they return the desired result. (In the version as written here, all the tests will fail.)
// Return true if str ends with target, false if it does not
function confirmEnding( str, target ) {
// You can do this in a single return statement
// with one === comparison in it. The .slice()
// method will help you here, and you only need
// to pass a single argument into it.
// You don't need any if statements, intermediate
// variables, or anything fancy.
// There are several other ways to do it too, including
// the approach shown on the MDN page.
}
function testEnding( str, target, desired ) {
var result = confirmEnding( str, target );
console.log(
'"' + str + '"',
'"' + target + '"',
'returns', result,
result === desired ? 'Good' : 'WRONG!'
);
}
testEnding( "Bastian", "n", true );
testEnding( "Connor", "n", false );
testEnding( "Walking on water and developing software from a specification are easy if both are frozen", "specification", false );
testEnding( "He has to give me a new name", "name", true );
testEnding( "Open sesame", "same", true );
testEnding( "Open sesame", "pen", false );
testEnding( "If you want to save our world, you must hurry ); We dont know how much longer we can withstand the nothing", "mountain", false );
You can use this function:
function confirmEnding(a, b) {
var l1 = a[a.length - 1];
var l2 = b[b.length - 1];
return l1 === l2;
}
Your error is that you're using substring. Try str.substr instead of substring
function confirmEnding (str, target) {
return str.substr(-1) == target.substr(-1);
}
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"));
const a = "Walking on water and developing software from a specification are easy if both are frozen",
b = "specification";
// your function
const equalLastLetter = (a, b) => a.substr(-1) === b.substr(-1);
console.log(equalLastLetter(a, b))
How about this?
function confirmEnding (str, target) {
var last = str.charAt(str.length-1);
var last2 = target.charAt(target.length-1);
return (last == last2);
}
You can use chatAt()
function confirmEnding (str, target) {
var last = str.charAt(str.length -1);
var last2 = target.charAt(target.length -1);
return last === last2 ;
}
Why have to check if last words are same so:
const confirmEnding = (str, target) => new RegExp(`${target}$`, '').test(str)
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"))
console.log(confirmEnding("Bastian", "n"))
console.log(confirmEnding("Connor", "n"))
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"))
console.log(confirmEnding("He has to give me a new name", "name"))
console.log(confirmEnding("Open sesame", "same"))
console.log(confirmEnding("Open sesame", "pen"))
console.log(confirmEnding("If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing", "mountain"))
Simplest way:
const confirmEnding = (_str, _target) => _str.charAt(_str.length - 1) === _target.charAt(_target.length - 1);
https://jsfiddle.net/pablodarde/hsdgjmzw/

JavaScript - Regex to remove code / special characters / numbers etc

Answer #Wiktor Stribiżew suggested:
function myValidate(word) {
return (word.length === 1 || /[^A-Z]/i.test(word)) ? true : false;
}
Hello during the creation of an array I have a function that will not allow words with certain characters etc to be added to the array
function myValidate(word) {
// No one letter words
if (word.length === 1) {
return true;
}
if (word.indexOf('^') > -1 || word.indexOf('$') > -1) {
return true;
}
return false;
}
It seems like not the proper way of going about this and ive been looking into a regex that would handle it but have not been successful implementing it, tried numerous efforts like:
if (word.match('/[^A-Za-z]+/g') ) {
return true;
}
can some one shed some light on the proper way of handling this?
I suggest using a simpler solution:
function myValidate(word) {
return (word.length === 1 || /[^A-Z]/i.test(word)) ? false : true;
}
var words = ["Fat", "Gnat", "x3-2741996", "1996", "user[50]", "definitions(edit)", "synopsis)"];
document.body.innerHTML = JSON.stringify(words.filter(x => myValidate(x)));
Where:
word.length === 1 checks for the string length
/[^A-Z]/i.test(word) checks if there is a non-ASCII-letter symbol in the string
If any of the above condition is met, the word is taken out of the array. The rest remains.
EDIT: using test instead of match
You want to use test() because it returns a bool telling you if you match the regex or not. The match(), instead, always returns the matched elements. Those may be cast to true by coercion. This is not what you want.
To sum it all up you can just use this one-liner (no if needed and no quotes either, cannot get any simpler):
return word.test(/^[a-zA-Z][a-zA-Z]+$/); // two letter words
You should whitelist characters instead of blacklisting. That's one of the principles in security. In your case, don't tell what is wrong, but tell what is right:
if (word.test('/^[a-zA-Z]+$/')) { // two letter words
return false;
}
This will return false for all words that contain ONLY [a-zA-Z] characters. I guess this is what you want.
Your regex, instead, looked for illegal characters by negating the character group with the leading ^.
Two recommendations:
Just use regex in a positive way (without negation) and it'll be a lot easier to understand.
Also, validation functions normally return true for good data and false for bad data.
It is more readable this way:
if (validate(data))
{
// that's some good data we have here!
}

if .html() has specific value

this might be a very basic question, but I would like to know how I can find out if .html() has a particular value (in this case a string). An example:
<p id="text">Hello this is a long text with numbers like 01234567</p>
and I would like to ask
var $text = $('#text');
if ($text.html() == '01234567')
of course this would not work. But how can I enhance another method to .html() that asks
if($text.html().contains() == '01234567');
Important to say is, that in my case I definitely will search for things who are seperated with a space, not like withnumberslike01234567 but indeed it would be interesting if that would work as well.
Thanks in advance!
(' ' + document.getElementById('text').textContent + ' ').indexOf(' 01234567 ') != -1
Fixes problem with the text at the beginning, doesn't abuse regex, and hooray for vanilla.js!
You can use indexOf:
var text = $('#text').html();
if(text.indexOf(" 01234567") != -1) {
// your logic
}
Your HTML might start with 01234567, though; in that case, you can do this:
if((' ' + text).indexOf(" 01234567") != -1) {
// your logic
}
Thanks, bjb568 and Felix Kling.
As I understand from OP, these are the test cases:
hello12348hello // false
hello 1234hello // false
hello012348 hello // false
hello 1234 hello // TRUE
1234hello // false
hello1234 // false
1234 hello // TRUE
hello 1234 // TRUE
// false
1234 // TRUE
1234 // TRUE
** Changing "" by any other white-space character (e.g. \t, \n, ...) should give same results.
As OP said:
for things who are separated with a space, not like withnumberslike01234567
So, hello 01234567withnumberslike is also wrong!!!
Creating the function:
function contains(value, searchString){
// option 1: splitting and finding a word separated by white spaces
var words = value.split(/\s+/g);
for (var i = 0; i < words.length; i++){
if (words[i] === searchString){
return true;
}
}
return false;
// option 1a: for IE9+
return value.split(/\s+/g).indexOf(searchString) > -1;
// option 2: using RegEx
return (new RegExp("\\b" + searchString + "\\b")).test(value);
return (new RegExp("(^|\\s)" + searchString + "($|\\s)")).test(value); // this also works
// option 3: Hardcoded RegEx
return /\b1234\b/.test(value);
}
See case tests here in jsFiddle
It will also accept tabs as well as whitespaces..
NOTE I wouldn't worry about using RegEx, it isn't fast as indexOf, but it stills really fast. It shouldn't be an issue, unless you iterate millions of times. If it would be the case, perhaps you'll need to rethink your approach because probably something is wrong..
I would say to you think about compatibility, there is a lot of users still using IE8, IE7, even IE6 (almost 10% right now - April, 2014). -- No longer an issue in 2016..
Also, it's preferred to maintain code standards.
Since, you are using jQuery you can use too .text() to find string:
var element = $(this);
var elementText = element.text();
if (contains(elementText, "1234"){
element.text(elementText.replace("1234", "$ 1234.00"))
.addClass("matchedString");
$('#otherElement').text("matched: 1234");
}
Thanks to #Karl-AndréGagnon for the tips.
\b: any boundary word (or start/end of the string)
^: start of the string
\s: Any whitespace character
$: end of the string
http://rubular.com/r/Ul6Ci4pcCf
You can use the String.indexOf method in JavaScript to determine whether or not one string is contained in another. If the string passed into indexOf is not in the string, then -1 is returned. This is the behavior you should utilize.
If ($test.html().indexOf("1234567890") != -1)
//Do Something
if($text.html().indexOf('01234567') != -1) {
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf

JavaScript switch case using enum

I have an "enum" declared like so:
var PlaceType = {
PASSABLE_TERRAIN: 1,
IMPASSABLE_TERRAIN: 0,
SOMEWHAT_PASSABLE_TERRAIN: 2,
PATH: 3
};
and a function declared like this:
setPlaceType(placeType) {
this.clear = false;
this.placeType = placeType;
alert("before switch "+(PlaceType.SOMEWHAT_PASSABLE_TERRAIN==this.placeType));
switch(this.placeType) {
case PlaceType.PASSABLE_TERRAIN: {
alert("Case PASSABLE");
break;
}
case PlaceType.IMPASSABLE_TERRAIN: {
alert("Case IMPASSABLE");
break;
}
case PlaceType.SOMEWHAT_PASSABLE_TERRAIN: {
alert("Case SOMEWHAT_PASSABLE");
break;
}
case PlaceType.PATH: {
alert("Case PATH");
break;
}
default: {
alert("case default");
}
}
}
if I call it like this:
setPlaceType(1);
I get the following alerts: "before switch true", "case default"
if I call it like this:
setPlaceType(2);
I get the following alerts: "before switch false", "case default"
In other words, the function is called with the proper argument, which, when doing (what it seems to me to be) the same comparison as the switch but via "==" I get correct behavior, but the switch never matches the values to the appropriate case. Does anybody know why?
The comparison operator will cast both operands to strings if either operator is a string. If you pass in a string, you are comparing string == number which will cast the number to a string and, in the case of passing the string '2', it will be true.
switch case comparison uses the identity operator === and will fail if the operands are not the same type.
long story short, make sure you are always passing a number if your cases are comparing against numbers, you can double check like this:
setPlaceType(placeType) {
if (typeof placeType !== 'number') {
throw new Error('You must pass a number to setPlaceType!');
}
...
}
also, you should be calling your function like this:
setPlaceType(PlaceType.PASSABLE_TERRAIN);
otherwise there's not really any point to using the "enumeration" (i use that term loosely) object.
Refering to this => Switch-Case for strings in Javascript not working as expected
Switch do a ===, while if do a ==.
Hope this help! have a nice day
When you are doing the comparison using == js is using type-coercion to cast the 2 operands to an intermediate type, string in this case, and thus compare them successfully.
So to get the effect to work with your switch statement, you will need to cast as such
this.placeType = parseint(placeType);
What you also got to learn here is that it is not really an ideal practice to compare 2 values in javascript using the == operator, instead use the === operator which also checks for the types to be the same. So in your case,
alert("before switch "+(PlaceType.SOMEWHAT_PASSABLE_TERRAIN==this.placeType));
would have failed if you would have used === as you are comparing an int and string
Working demo here: http://jsfiddle.net/pratik136/ATx8c/
The matching case is determined using the === identity operator, not the == equality operator. The expressions must match without any type conversion. It would fail if you are passing in a string and not an integer.
setPlaceType(1); //"Case PASSABLE"
setPlaceType("1"); //"case default"
Example running your code with the above lines: jsFiddle
So if you are saying it is failing, you are probably comparing a string to a number. Use parseInt.
this.placeType = parseint(placeType,10);
Another way to use enum for switch case:
const PlaceType = Object.freeze({
PASSABLE_TERRAIN: 1,
IMPASSABLE_TERRAIN: 0,
SOMEWHAT_PASSABLE_TERRAIN: 2,
PATH: 3
});
function setPlaceType(placeType){
return({
0:"Case IMPASSABLE_TERRAIN",
1:"Case PASSABLE_TERRAIN",
2:"Case SOMEWHAT_PASSABLE_TERRAIN",
3:"PATH"
}[placeType]);
}

How can I subclass Boolean to change string representation without negative side effects outside of my function?

I need to a way to wrap a boolean value such that comparisons are not broken and the string result is different than 'false' or 'true' without altering the global boolean values
function TestIt(bool){
if(wrapper(bool) == true)
return "it was: " + wrapper(bool)
if(wrapper(bool) == false)
return "it was: " + wrapper(bool)
return "no dice"
}
e.g.
var result;
result = TestIt(true);
// "it was: True"
result = TestIt(false);
// "it was: False"
The attempts I have written have not been able to achieve all of the conditions below at the same time:
var initial = true;
var result1;
var result2;
(function(){
result1 = wrapper(true);
result2 = wrapper(true);
})()
// result1 == result2
// result1 == true
// result1.toString() != initial.toString()
// initial.toString() == true.toString()
// initial.toString() == (new Boolean(true)).toString()
Can anyone help me please?
I need this (automatic) alternate string conversion so that I can duplicate a string created on a server environment using a different language and match it exactly.
~~~~~~
Edit
~~~~~~
I forgot to mention that the trouble I am running into is the Boolean "valueOf" method that is called instead of toString (apparently) for string concatenation.
~~~~~~
Edit #2
~~~~~~
This would also need to work for false. I just left that out for brevity. However, wrapper(false) == false gave me a headache.
~~~~~~
Edit Final
~~~~~~
It turns out (in the answers below), that you can't override the default behavior like I wanted if string concatenation is used. I am going to work on using an array to solve my problem and then doing custom conversions when I join it back together. It seems like Javascript requires an oddball approach to a conceptually simple problem.
Code Example for command line:
function boolish(a){a=new Boolean(a);a.toString=function(){return this.valueOf()?"True":"False"};return a};
boolish(false) == false
boolish(true) == true
boolish(false) + " or " + boolish(true)
[boolish(false) , " or " , boolish(true)].join("~~~~~~~~")
I don't understand why you think you need this to happen automatically via toString(). If you have a "plain" boolean you can (obviously) use it in any comparisons as normal, but if you want to get some non-standard text when concatenated just specify it at the time. For example, if you wanted "TRUE" and "FALSE" all in caps:
var myBool1 = false,
myBool2 = true;
alert("The value of myBool1 is: " + (myBool1?"TRUE":"FALSE"));
Or you could write a little function:
function boolToString(val) {
return val ? "True enough" : "That's a lie!";
}
alert("The value of myBool2 is: " + boolToString(myBool2));
EDIT According to the following SO question (and answers): valueOf() vs. toString() in Javascript your requirement can't be done. The string concatenation + operator will always end up using valueOf rather than toString. I agree that this is weird. The workaround is to concatenate the strings without using the + operator, but I gather you don't want to do that.
You can do something like:
function myBool(value) {
this.value = value;
}
myBool.prototype.toString = function() {
return 'The value is ' + (this.value? 'true' : 'false');
}
var x = new myBool(true);
alert(x); // 'The value is true'

Categories

Resources