I want to check if 3 RGB values are basically equal but sometimes the values are 1 or even 2 out either way so it's not so straightforward. So 90,90,90 should be equal as should 90,88,90.
At the minute the best I came up with was something like:
if (r != g && r != b) {
if ((r != b && r != (b - 1))) {
// etc
}
}
Expected output:
91,90,90 = true
93,89,93 = false
91,90,89 = true
You can use every() on the array and check if the absolute difference b/w the each value with minimum(or maximum) is less than 2 or equal to 2
const checkRBG = arr => {
let min = Math.min(...arr);
return arr.every(x => Math.abs(min-x) <=2);
}
const tests = [
[91,90,90],
[93,89,93],
[91,90,89],
[90,88,92]
]
tests.forEach(x => console.log(checkRBG(x)))
Do it right
If you want to do if() statements, do this:
var foo = 1;
var baz = true;
var bar = "Hello";
// Not equals (abstract equality)
if(foo !== 2) {
console.log('Not 2');
}
// Equals (abstract equality)
if(baz == "false") {
console.log('false!');
}
// Equals (strict equality)
if(bar===new String('Hello')) {
console.log('Hello as a new String!');
} /* Not equals (strict equality) */ else if(bar==="Hello") {
console.log('Hello as a string');
}
but not != or =
IN FACT I JUST WANT TO SAY " DON'T USE = BUT USE == OR ===" (Explanation down there)
Explanation
ABSTRACT EQUALITY
== returns true if it has any equality EXCEPT equality of types
e.g...
console.log(1 == "1"); // Output: true
console.log(1 == true); // Output: true
console.log("foo" == new String('foo')); // Output: true
STRICT EQUALITY
=== returns false if it has any inequality (literally ANY inequality)
e.g...
console.log(1 === "1"); // Output: false
console.log(1 === true); // Output: false
console.log("foo" === new String('foo')); // Output: false
If I compare "a" and "b", that should be false.
If I compare "a" and "a", that should be true.
If I compare "" and null, that should be true.
I could write my own method, but thought there was perhaps a JavaScript shortcut.
Edit: I was thinking something like this:
areDbSame(s1, s2) {
if (s1 === null) s1 = "";
if (s2 === null) s2 = "";
return s1 === s2;
}
Edit2: Settled on this version:
areDbSame(s1, s2) {
return (s1 === null ? "" : s1) === (s2 === null ? "" : s2);
}
Just before you test the equality of your string, you could do a simple one line enforcement, by converting to '' in the case of null. For example (if you also don't care about undefined, false, etc):
// testString becomes the one you are testing
var testString = myString || '';
If you only want to ensure null is blank
var testString = (myString === null) ? '' : myString;
Then you can simply do your string comparisons using testString, and not worry about the null equalities.
IMO this is the cleanest answer because it doesn't convolute the original equality testing of javascript strings. It is the same as saying, let's split the problem up into two parts.
1) When should my string be considered blank, and
2) Now I can just check for regular string equality.
function areEqualStrings(a, b) {
var otherEqualValues = ['', null];
if(typeof a === 'string' && typeof b === 'string') {
return a === b;
} else if(otherEqualValues.indexOf(a) > -1 && otherEqualValues.indexOf(b) > -1) {
return !a === !b;
} else {
return false;
}
}
When coercing JavaScript values, !null is true and !'' is true, so those would result in being equal.
Here's the test (screenshotted from my console):
This function should do it. It type checks first and short circuits otherwise.
function stringCompare(a, b) {
if (((a === null || typeof a === 'string') ||
(b === null || typeof b === 'string')) &&
((a === '' && b === null) ||
(b === '' && a === null) ||
(a === b))) {
return true;
}
return false;
}
No it hasn`t. The two first cases you can do naturally using operator =.
The third case it is impossible because "" is considered a empty string and null has any type. So they never can be true naturally. To do this, you have to write your own method.
Just to be clear. You can use operators = (equal) to do comparison:
== equal to
`x == 8 false
x == 5 true
x == "5" true
=== equal value and equal type
x === 5 true
x === "5" false
Hope it helps
In this function the user selects a value in the dropdown menu and whatever value is selected, it would change var B to its corresponding value.
function test(){
var A = ["", "A", "B", "C"];
var B = document.getElementById("myfile");
if(A.value = "A"){
B.selectedIndex = [2];
}
else if(A.value = "B"){
B.selectedIndex = [4];
}
else if(A.value = "C"){
B.selectedIndex = [1];
}
}
The problem I am having is that every time I select B or C, it always defaults to index [2] and not [4] or [1].
You're assigning when you mean to compare. Use ==, not =, for comparison.
if(A.value == "A"){
B.selectedIndex = [2];
}
else if(A.value == "B"){
B.selectedIndex = [4];
}
else if(A.value == "C"){
B.selectedIndex = [1];
}
= is assignment
== is test for equality for content
=== is test for equality for content and data type
In your case, = is certainly a typo. I'd recommend using === for maximum program stability.
Some folk tend to write "A" == A.value so a misplaced assignment gives you a syntax error.
You're assigning the value in your ifs not testing it. This will return the value that is assigned. The if condition will be true unless the following values are assigned and therefore returned, false, 0, an empty string, null, undefined or NaN. That's why you are entering the block of the first if statement.
Change the single equals to double or triple equals.
if(A.value == "A"){
B.selectedIndex = [2];
}
else if(A.value == "B"){
B.selectedIndex = [4];
}
else if(A.value == "C"){
B.selectedIndex = [1];
}
Use == not =
Your statement checks if its possible to set the value.(Every time...)
I'm doing some trouble-shooting and want to add a check that a parameter to a function is a number. How do I do this?
Something like this...
function fn(id) {
return // true iff id is a number else false
}
Even better is if I can check that the parameter is a number AND a valid integer.
function fn(id) {
return typeof(id) === 'number';
}
To also check if it’s an integer:
function fn(id) {
return typeof(id) === 'number' &&
isFinite(id) &&
Math.round(id) === id;
}
i'd say
n === parseInt(n)
is enough. note three '===' - it checks both type and value
Check if the type is number, and whether it is an int using parseInt:
if (typeof id == "number" && id == parseInt(id))
=== means strictly equals to and == checks if values are equal.
that means "2"==2 is true but "2"===2 is false.
using regular expression
var intRegex = /^\d+$/;
if(intRegex.test(num1)) {
//num1 is a valid integer
}
example of
== vs. ===
function fn(id){
if((parseFloat(id) == parseInt(id)) && !isNaN(id)){
return true;
} else {
return false;
}
}
function fn(id) {
var x = /^(\+|-)?\d+$/;
if (x.test(id)) {
//integer
return true;
}
else {
//not an integer
return false;
}
}
Test fiddle: http://jsfiddle.net/xLYW7/
How do I perform case insensitive string comparison in JavaScript?
The simplest way to do it (if you're not worried about special Unicode characters) is to call toUpperCase:
var areEqual = string1.toUpperCase() === string2.toUpperCase();
EDIT: This answer was originally added 9 years ago. Today you should use localeCompare with the sensitivity: 'accent' option:
function ciEquals(a, b) {
return typeof a === 'string' && typeof b === 'string'
? a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0
: a === b;
}
console.log("'a' = 'a'?", ciEquals('a', 'a'));
console.log("'AaA' = 'aAa'?", ciEquals('AaA', 'aAa'));
console.log("'a' = 'á'?", ciEquals('a', 'á'));
console.log("'a' = 'b'?", ciEquals('a', 'b'));
The { sensitivity: 'accent' } tells localeCompare() to treat two variants of the same base letter as the same unless they have different accents (as in the third example) above.
Alternatively, you can use { sensitivity: 'base' }, which treats two characters as equivalent as long as their base character is the same (so A would be treated as equivalent to á).
Note that the third parameter of localeCompare is not supported in IE10 or lower or certain mobile browsers (see the compatibility chart on the page linked above), so if you need to support those browsers, you'll need some kind of fallback:
function ciEqualsInner(a, b) {
return a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0;
}
function ciEquals(a, b) {
if (typeof a !== 'string' || typeof b !== 'string') {
return a === b;
}
// v--- feature detection
return ciEqualsInner('A', 'a')
? ciEqualsInner(a, b)
: /* fallback approach here */;
}
Original answer
The best way to do a case insensitive comparison in JavaScript is to use RegExp match() method with the i flag.
Case-insensitive search
When both strings being compared are variables (not constants), then it's a little more complicated 'cause you need to generate a RegExp from the string but passing the string to RegExp constructor can result in incorrect matches or failed matches if the string has special regex characters in it.
If you care about internationalization don't use toLowerCase() or toUpperCase() as it doesn't provide accurate case-insensitive comparisons in all languages.
http://www.i18nguy.com/unicode/turkish-i18n.html
As said in recent comments, string::localeCompare supports case insensitive comparisons (among other powerful things).
Here's a simple example
'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0
And a generic function you could use
function equalsIgnoringCase(text, other) {
return text.localeCompare(other, undefined, { sensitivity: 'base' }) === 0;
}
Note that instead of undefined you should probably enter the specific locale you are working with. This is important as denoted in the MDN docs
in Swedish, ä and a are separate base letters
Sensitivity options
Browser support
As of time of posting, UC Browser for Android and Opera Mini do not support locale and options parameters. Please check https://caniuse.com/#search=localeCompare for up to date info.
Update:
As per the comments, previous answer checks for source contains keyword, to make it equality check added ^ and $.
(/^keyword$/i).test(source)
With the help of regular expression also we can achieve.
(/keyword/i).test(source)
/i is for ignoring case. If not necessary we can ignore and test for NOT case sensitive matches like
(/keyword/).test(source)
Remember that casing is a locale specific operation. Depending on scenario you may want to take that in to account. For example, if you are comparing names of two people you may want to consider locale but if you are comparing machine generated values such as UUID then you might not. This why I use following function in my utils library (note that type checking is not included for performance reason).
function compareStrings (string1, string2, ignoreCase, useLocale) {
if (ignoreCase) {
if (useLocale) {
string1 = string1.toLocaleLowerCase();
string2 = string2.toLocaleLowerCase();
}
else {
string1 = string1.toLowerCase();
string2 = string2.toLowerCase();
}
}
return string1 === string2;
}
if you are concerned about the direction of the inequality (perhaps you want to sort a list)
you pretty-much have to do case-conversion, and as there are more lowercase characters in unicode than uppercase toLowerCase is probably the best conversion to use.
function my_strcasecmp( a, b )
{
if((a+'').toLowerCase() > (b+'').toLowerCase()) return 1
if((a+'').toLowerCase() < (b+'').toLowerCase()) return -1
return 0
}
Javascript seems to use locale "C" for string comparisons so the resulting ordering will
be ugly if the strings contain other than ASCII letters. there's not much that can be done about that without doing much more detailed inspection of the strings.
I have recently created a micro library that provides case-insensitive string helpers: https://github.com/nickuraltsev/ignore-case. (It uses toUpperCase internally.)
var ignoreCase = require('ignore-case');
ignoreCase.equals('FOO', 'Foo'); // => true
ignoreCase.startsWith('foobar', 'FOO'); // => true
ignoreCase.endsWith('foobar', 'BaR'); // => true
ignoreCase.includes('AbCd', 'c'); // => true
ignoreCase.indexOf('AbCd', 'c'); // => 2
Use RegEx for string match or comparison.
In JavaScript, you can use match() for string comparison,
don't forget to put i in the regular expression. This flag will force case insensitive testing.
Example:
To confirm the string test of any case is included anywhere inside the matchString variable
var matchString = "Test";
if (matchString.match(/test/i)) {
alert('matchString contains the substring "test" case insensitive');
}
else {
alert('matchString does not contain the substring "test" case insensitive');
}
To confirm matchString variable only contains test of any case, and no additional characters, then use zero-width assertions ^ and $ in the regular expression. These will require test to appear directly after the start of the string and directly before the end of the string respecitivly.
var matchString = "Test";
if (matchString.match(/^test$/i)) {
alert('matchString equals "test" case insensitive');
}
else {
alert('matchString does not equal "test" case insensitive');
}
Suppose we want to find the string variable needle in the string variable haystack. There are three gotchas:
Internationalized applications should avoid string.toUpperCase and string.toLowerCase. Use a regular expression which ignores case instead. For example, var needleRegExp = new RegExp(needle, "i"); followed by needleRegExp.test(haystack).
In general, you might not know the value of needle. Be careful that needle does not contain any regular expression special characters. Escape these using needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
In other cases, if you want to precisely match needle and haystack, just ignoring case, make sure to add "^" at the start and "$" at the end of your regular expression constructor.
Taking points (1) and (2) into consideration, an example would be:
var haystack = "A. BAIL. Of. Hay.";
var needle = "bail.";
var needleRegExp = new RegExp(needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i");
var result = needleRegExp.test(haystack);
if (result) {
// Your code here
}
Lots of answers here, but I like to add a sollution based on extending the String lib:
String.prototype.equalIgnoreCase = function(str)
{
return (str != null
&& typeof str === 'string'
&& this.toUpperCase() === str.toUpperCase());
}
This way you can just use it like you do in Java!
Example:
var a = "hello";
var b = "HeLLo";
var c = "world";
if (a.equalIgnoreCase(b)) {
document.write("a == b");
}
if (a.equalIgnoreCase(c)) {
document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
document.write("b != c");
}
Output will be:
"a == b"
"b != c"
String.prototype.equalIgnoreCase = function(str) {
return (str != null &&
typeof str === 'string' &&
this.toUpperCase() === str.toUpperCase());
}
var a = "hello";
var b = "HeLLo";
var c = "world";
if (a.equalIgnoreCase(b)) {
document.write("a == b");
document.write("<br>");
}
if (a.equalIgnoreCase(c)) {
document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
document.write("b != c");
}
There are two ways for case insensitive comparison:
Convert strings to upper case and then compare them using the strict operator (===).
Pattern matching using string methods:
Use the "search" string method for case insensitive search.
<!doctype html>
<html>
<head>
<script>
// 1st way
var a = "apple";
var b = "APPLE";
if (a.toUpperCase() === b.toUpperCase()) {
alert("equal");
}
//2nd way
var a = " Null and void";
document.write(a.search(/null/i));
</script>
</head>
</html>
If both strings are of the same known locale, you may want to use Intl.Collator object like this:
function equalIgnoreCase(s1: string, s2: string) {
return new Intl.Collator("en-US", { sensitivity: "base" }).compare(s1, s2) === 0;
}
Obviously, you may want to cache the Collator for better efficiency.
The advantages of this approach is that it should be much faster than using RegExps and is based on an extremely customizable (see description of locales and options constructor parameters in the article above) set of ready-to-use collators.
I like this quick shorthand variation -
export const equalsIgnoreCase = (str1, str2) => {
return (!str1 && !str2) || (str1 && str2 && str1.toUpperCase() == str2.toUpperCase())
}
Quick in processing, and does what it is intended to.
I wrote a extension. very trivial
if (typeof String.prototype.isEqual!= 'function') {
String.prototype.isEqual = function (str){
return this.toUpperCase()==str.toUpperCase();
};
}
str = 'Lol', str2 = 'lOl', regex = new RegExp('^' + str + '$', 'i');
if (regex.test(str)) {
console.log("true");
}
Even this question has already been answered. I have a different approach to using RegExp and match to ignore case sensitivity. Please see my link
https://jsfiddle.net/marchdave/7v8bd7dq/27/
$("#btnGuess").click(guessWord);
function guessWord() {
var letter = $("#guessLetter").val();
var word = 'ABC';
var pattern = RegExp(letter, 'gi'); // pattern: /a/gi
var result = word.match(pattern);
alert('Ignore case sensitive:' + result);
}
Convert both to lower string (only once for performance reasons) and compare them with inline ternary operator:
function strcasecmp(s1,s2){
s1=(s1+'').toLowerCase();
s2=(s2+'').toLowerCase();
return s1>s2?1:(s1<s2?-1:0);
}
How about NOT throwing exceptions and NOT using slow regex?
return str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase();
The above snippet assumes you don't want to match if either string is null or undefined.
If you want to match null/undefined, then:
return (str1 == null && str2 == null)
|| (str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase());
If for some reason you care about undefined vs null:
return (str1 === undefined && str2 === undefined)
|| (str1 === null && str2 === null)
|| (str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase());
Since no answer clearly provided a simple code snippet for using RegExp, here's my attempt:
function compareInsensitive(str1, str2){
return typeof str1 === 'string' &&
typeof str2 === 'string' &&
new RegExp("^" + str1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "$", "i").test(str2);
}
It has several advantages:
Verifies parameter type (any non-string parameter, like undefined for example, would crash an expression like str1.toUpperCase()).
Does not suffer from possible internationalization issues.
Escapes the RegExp string.
If you know you're dealing with ascii text then you can just use a uppercase/lowercase character offset comparison.
Just make sure the string your "perfect" string (the one you want to match against) is lowercase:
const CHARS_IN_BETWEEN = 32;
const LAST_UPPERCASE_CHAR = 90; // Z
function strMatchesIgnoreCase(lowercaseMatch, value) {
let i = 0, matches = lowercaseMatch.length === value.length;
while (matches && i < lowercaseMatch.length) {
const a = lowercaseMatch.charCodeAt(i);
const A = a - CHARS_IN_BETWEEN;
const b = value.charCodeAt(i);
const B = b + ((b > LAST_UPPERCASE_CHAR) ? -CHARS_IN_BETWEEN : CHARS_IN_BETWEEN);
matches = a === b // lowerA === b
|| A === b // upperA == b
|| a === B // lowerA == ~b
|| A === B; // upperA == ~b
i++;
}
return matches;
}
For better browser compatibility you can rely on a regular expression. This will work in all web browsers released in the last 20 years:
String.prototype.equalsci = function(s) {
var regexp = RegExp("^"+this.replace(/[.\\+*?\[\^\]$(){}=!<>|:-]/g, "\\$&")+"$", "i");
return regexp.test(s);
}
"PERSON#Ü.EXAMPLE.COM".equalsci("person#ü.example.com")// returns true
This is different from the other answers found here because it takes into account that not all users are using modern web browsers.
Note: If you need to support unusual cases like the Turkish language you will need to use localeCompare because i and I are not the same letter in Turkish.
"I".localeCompare("i", undefined, { sensitivity:"accent"})===0// returns true
"I".localeCompare("i", "tr", { sensitivity:"accent"})===0// returns false
This is an improved version of this answer.
String.equal = function (s1, s2, ignoreCase, useLocale) {
if (s1 == null || s2 == null)
return false;
if (!ignoreCase) {
if (s1.length !== s2.length)
return false;
return s1 === s2;
}
if (useLocale) {
if (useLocale.length)
return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
else
return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
}
else {
if (s1.length !== s2.length)
return false;
return s1.toLowerCase() === s2.toLowerCase();
}
}
Usages & tests:
String.equal = function (s1, s2, ignoreCase, useLocale) {
if (s1 == null || s2 == null)
return false;
if (!ignoreCase) {
if (s1.length !== s2.length)
return false;
return s1 === s2;
}
if (useLocale) {
if (useLocale.length)
return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
else
return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
}
else {
if (s1.length !== s2.length)
return false;
return s1.toLowerCase() === s2.toLowerCase();
}
}
// If you don't mind extending the prototype.
String.prototype.equal = function(string2, ignoreCase, useLocale) {
return String.equal(this.valueOf(), string2, ignoreCase, useLocale);
}
// ------------------ TESTS ----------------------
console.log("Tests...");
console.log('Case sensitive 1');
var result = "Abc123".equal("Abc123");
console.assert(result === true);
console.log('Case sensitive 2');
result = "aBC123".equal("Abc123");
console.assert(result === false);
console.log('Ignore case');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);
console.log('Ignore case + Current locale');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);
console.log('Turkish test 1 (ignore case, en-US)');
result = "IiiI".equal("ıiİI", true, "en-US");
console.assert(result === false);
console.log('Turkish test 2 (ignore case, tr-TR)');
result = "IiiI".equal("ıiİI", true, "tr-TR");
console.assert(result === true);
console.log('Turkish test 3 (case sensitive, tr-TR)');
result = "IiiI".equal("ıiİI", false, "tr-TR");
console.assert(result === false);
console.log('null-test-1');
result = "AAA".equal(null);
console.assert(result === false);
console.log('null-test-2');
result = String.equal(null, "BBB");
console.assert(result === false);
console.log('null-test-3');
result = String.equal(null, null);
console.assert(result === false);
We could also do this using ASCII:
function toLower(a){
let c = "";
for(let i = 0;i<a.length;i++){
let f = a.charCodeAt(i);
if(f < 95){
c += String.fromCharCode(f+32);
}
else{
c += a[i];
}
}
return c;
}
function compareIt(a,b){
return toLower(a)==toLower(b);
}
console.log(compareIt("An ExamPlE" , "an example"));