This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
IE9 array does not support indexOf
My Code:
var arrFruits = ['apple', 'banana', 'carrot', 'dates'];
var position = arrFruits.indexOf( 'carrot' );
position > -1 && arrFruits.splice( position, 1 );
alert( arrFruits );
The above code is displaying the result as apple, banana, dates in Chrome. But it is not working in IE9.
It may be issue of .indexOf not being supported. It basically is supported in IE9 unless some malicious doctype is triggering it to render page in IE7/8 mode. Than Array.indexOf method is not supported.
I suggest using HTML5 doctype for example (<!DOCTYPE html>) to make sure IE9 is rendering correctly.
till IE8 it doesn't have .indexOf method , you can add it like this, if you are using IE9 check for compatibility mode
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
What is this line for
position > -1 && arrFruits.splice( position, 1 );
It evaluateto either true or false and then you don't do anything with it.that's probably causing a syntax error in IE, which the more forgiving Javascript engines on chrome and Firefox are ignoring.
Maybe you meant to make an if statement?
if(position > -1) {
arrFruits.splice( position, 1 );
}
Related
This question already has answers here:
Array.prototype.includes vs. Array.prototype.indexOf
(11 answers)
Closed 5 years ago.
We have list of ids i.e.1,2,3.
There is a function which accepts id and returns if passed id is in this list or not:
function isIdInList(id) {
return [1,2,3].includes(id);
}
OR
function isIdInList(id) {
return [1,2,3].indexOf(id) > -1;
}
i.e. isIdInList(1) returns true.
isIdInList(5) returns false.
What is the best solution to this, 1 of above two or any other? (Considering the list is hardcoded & The solution should be compatible for all browsers.)
Array.prototype.includes comes from ES2016 specification. It is not supported very well in all web browsers (especially if they are not up-to-date...), so you should probably use the solution with indexOf for full compatibility.
Of course, if you compile your code with Babel or Traceur, you can use includes but it would be wise to add a polyfill like the one suggested in MDN documentation:
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(searchElement, fromIndex) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If len is 0, return false.
if (len === 0) {
return false;
}
// 4. Let n be ? ToInteger(fromIndex).
// (If fromIndex is undefined, this step produces the value 0.)
var n = fromIndex | 0;
// 5. If n ≥ 0, then
// a. Let k be n.
// 6. Else n < 0,
// a. Let k be len + n.
// b. If k < 0, let k be 0.
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(searchElement, elementK) is true, return true.
// c. Increase k by 1.
if (sameValueZero(o[k], searchElement)) {
return true;
}
k++;
}
// 8. Return false
return false;
}
});
}
This question already has answers here:
Determine whether an array contains a value [duplicate]
(18 answers)
How to check if jQuery object exist in array?
(5 answers)
Closed 9 years ago.
I have to check whether a variable is equal to a given number or another. For example I am doing this right now.
if (num == 1 || num == 3 || num == 4 || etc.) {
// Do something
} else if (num == 2 || num == 7 || num == 11 || etc.) {
// Do something
}
I thought there should be an easier way. for example an array of all numbers per if statement.
var array1 = [1,3,4,5,6,8,9,10 etc.]
var array2 = [2,7,11,12,13,14 etc.]
And then see if the number is equal to anything inside one of these arrays. But I don't know how to do it..
The indexOf() method searches the array for the specified item, and returns its position.
var array1 = [1,3,4,5,6,8,9,10];
var a = array1.indexOf(46); //a = -1; if not found
If you need to support environments that don't have .indexOf(), you could implement the MDN fix.
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this === void 0 || this === null) throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) return -1;
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n !== n) // shortcut for verifying if it's NaN
n = 0;
else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
if (n >= len) return -1;
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) return k;
}
return -1;
};
}
Since you're asking for jQuery, there is .inArray(). This returns a -1 if it isn't found, else the index of the matching element.
why dont you do a simple for loop?
for(var i = 0; i < array1.length; i++)
{
if(array[i] == num)
{
// do something
break;
}
}
You might use inArray function (http://api.jquery.com/jQuery.inArray/)
<script>var arr = [ 4, "Pete", 8, "John" ];
var $spans = $("span");
$spans.eq(0).text(jQuery.inArray("John", arr));
$spans.eq(1).text(jQuery.inArray(4, arr));
$spans.eq(2).text(jQuery.inArray("Karl", arr));
$spans.eq(3).text(jQuery.inArray("Pete", arr, 2));
</script>
Output:
"John" found at 3
4 found at 0
"Karl" not found, so -1
"Pete" is in the array, but not at or after index 2, so -1
You can do it without jQuery:
if(array1.indexOf(num1) >= 0)//if -1, then not found
You don't need to use jQuery. This is a built in function called indexOf:
if ( arr.indexOf(item) !== -1 ) {
// item is in array
}
In Fabric.js you see a lot of places where a code block enclosed in a condition check of format:
if (!Array.prototype.indexOf) {} or
if (!Array.prototype.forEach) {} etc.
Isn't the result always false? Why checking the boolean value of a method?
Thanks.
Those tests pass when the functions aren't defined.
Old browsers don't have those functions. That's why they're testing for their presence.
The MDN gives the same example (classical) of this test used to define a replacement function for array.indexOf (for IE before version 9) :
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
It is checking for the existence of the method. If it doesn't exist, it will be undefined, so it'll be doing !undefined, resulting in true.
I would assume that the code is introducing a shim if it doesn't exist.
I wasn't aware of the bad crossbrowser compatibility of array.indexOf() . But now that I am, I need to find a way to achieve the same thing but without using the previous method.
I tried googling for a while, but found no real convincing answers. For now, I am doing it with loops (but this is slow and I am sure there are better ways)
Side Notes:
I can't use jQuery or any other libraries/frameworks.
It doesn't necessarily need to return the index (a simply true/false
will be ok)
I thought it is not necessary to share my code, since you all know how array-loop check looks like (plus it will lower your IQ)
Here is how inArray is implemented in jQuery:
function inArray(elem, array, i) {
var len;
if ( array ) {
if ( array.indexOf ) {
return array.indexOf.call( array, elem, i );
}
len = array.length;
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
for ( ; i < len; i++ ) {
// Skip accessing in sparse arrays
if ( i in array && array[ i ] === elem ) {
return i;
}
}
}
return -1;
}
You can not use jQuery but why not use their implementation? :-)
Best regards!
From MDN:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
This checks if it sees a native implementation, if not implement it.
Notable Quirks:
t.length >>> 0; is an unsigned shift for force this to a positive number
For now, I am doing it with loops (but this is slow and I am sure there are better ways)
No matter what you do, it will at the end of the day involve loops. Unless you invent a O(1) algorithm for searching inside an array. There is nothing wrong with using a loop to find the corresponding element. You could even extend the built-in array object with this method so that you can reuse it.
I have a version number with 3 digits as a String,
var version = "1.2.3";
and would like to compare it to another version. To see if version is newer than otherversion,
var otherVersion = "1.2.4";
How would you do it?
Pseudo:
Split both on .
Compare parts sequentially: Major -> Minor -> Rev (if part exist for both versions).
If oV[n] > v[n]: oV is greatest.
Else: Compare next subpart.
(See #arhorns answer for a elegant implementation)
The problem with most of the submitted versions is they can't handle any number of version parts (eg. 1.4.2 .. 1.2 etc) and/or they have the requirement of the version part being a single digit, which is not that common actually.
Improved compareVersions() function
This function will return 1 if v1 is greater than v2, -1 if v2 is greater
and 0 if the versions are equal (handy for custom sorting as well)
I'm not doing any error checking on the inputs.
function compareVersions (v1, v2)
{
v1 = v1.split('.');
v2 = v2.split('.');
var longestLength = (v1.length > v2.length) ? v1.length : v2.length;
for (var i = 0; i < longestLength; i++) {
if (v1[i] != v2[i]) {
return (v1 > v2) ? 1 : -1
}
}
return 0;
}
You may want to use the following implementation (based on jensgram's solution):
function isNewer(a, b) {
var partsA = a.split('.');
var partsB = b.split('.');
var numParts = partsA.length > partsB.length ? partsA.length : partsB.length;
var i;
for (i = 0; i < numParts; i++) {
if ((parseInt(partsB[i], 10) || 0) !== (parseInt(partsA[i], 10) || 0)) {
return ((parseInt(partsB[i], 10) || 0) > (parseInt(partsA[i], 10) || 0));
}
}
return false;
}
console.log(isNewer('1.2.3', '1.2.4')); // true
console.log(isNewer('1.2.3', '1.2.0')); // false
console.log(isNewer('1.2.3', '1.2.3.1')); // true
console.log(isNewer('1.2.3', '1.2.2.9')); // false
console.log(isNewer('1.2.3', '1.2.10')); // true
Note that the use of parseInt() is necessary, because otherwise the last test would return false: "10" > "3" returns false.
If indeed you only have a single digit in each part why not just use straight comparison?
>>> var version = "1.2.3"; var otherVersion = "1.2.4"; version < otherVersion
true
It seems also to work with abbreviated versions:
>>> '1.2' > '1.2.4'
false
>>> '1.3' > '1.2.4'
true
function VersionValue(var str)
{
var tmp = str.split('.');
return (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
}
if (VersionValue(version) > VersionValue(otherVersion))...
for example
Since I'm bored, here's an approach similar to our decimal system (tens, hundreds, thousands, etc) which uses a regex callback instead of a loop:
function compareVersion(a, b) {
var expr = /\d+/g, places = Math.max(a.split(expr).length, b.split(expr).length);
function convert(s) {
var place = Math.pow(100, places), total = 0;
s.replace(expr,
function (n) {
total += n * place;
place /= 100;
}
);
return total;
};
if (convert(a) > convert(b)) {
return a;
}
return b;
}
It returns the greater version, e.g.:
compareVersion('1.4', '1.3.99.32.60.4'); // => 1.4
function isCorrectVersion(used,required){
var used = parseFloat("0."+used.replace(/\./gi,""));
var required = parseFloat("0."+required.replace(/\./gi,""));
return (used < required) ? false : true;
}
I use this to compare jQuery functions and it seems to work fine, also comparing for example 1.4 with 1.4.1 or 1.4.1 with 1.4.11.
I couldnt find an answer that returns 1, 0 or -1 and takes care of both trailing .0 and two digit partials, so here goes. This should support all cases where all the partials are numbers (see the tests at the bottom).
/*
* Returns 1 if v1 is newer, -1 if v2 is newer and 0 if they are equal.
* .0s at the end of the version will be ignored.
*
* If a version evaluates to false it will be treated as 0.
*
* Examples:
* compareVersions ("2.0", "2") outputs 0,
* compareVersions ("2.0.1", "2") outputs 1,
* compareVersions ("0.2", "0.12.1") outputs -1,
*
*/
function compareVersions (version1, version2) {
var version1 = version1 ? version1.split('.') : ['0'],
version2 = version2 ? version2.split('.') : ['0'],
longest = Math.max(version1.length, version2.length);
for (var i = 0; i < longest; i++) {
/*
* Convert to ints so that we can compare two digit parts
* properly. (Otherwise would "2" be greater than "12").
*
* This returns NaN if the value is undefined, so we check for
* NaN later.
*/
var v1Part = parseInt(version1[i]),
v2Part = parseInt(version2[i]);
if (v1Part != v2Part) {
// version2 is longer
if (isNaN(v1Part)) {
/*
* Go through the rest of the parts of version 2. If it is only zeros,
* consider the versions equal, otherwise consider version 2 as newer.
*/
for (var j = i; j < longest; j++) {
if (parseInt(version2[j]) != 0) return -1;
}
// version1 is longer
} else if (isNaN(v2Part)) {
for (var j = i; j < longest; j++) {
if (parseInt(version1[j]) != 0) return 1;
}
// versions are equally long
} else {
return (v1Part > v2Part) ? 1 : -1;
}
return 0;
}
}
return 0;
}
console.log(compareVersions("1", "1") === 0);
console.log(compareVersions("1.1", "1") === 1);
console.log(compareVersions("1.1.1", "1") === 1);
console.log(compareVersions("1", "1.1.1") === -1);
console.log(compareVersions("0.3", "0.3.0.0.1") === -1);
console.log(compareVersions("0.3", "0.3.0") === 0);
console.log(compareVersions("0.3.0.0.1", "0.3") === 1);
console.log(compareVersions("0.3.0", "0.3") === 0);
console.log(compareVersions("0.12", "0.2") === 1);
console.log(compareVersions("0.2", "0.12") === -1);
console.log(compareVersions("0.12.0", "0.2") === 1);
console.log(compareVersions("0.02.0", "0.2") === 0);
console.log(compareVersions("0.01.0", "0.2") === -1);
With one of the comparison operators.
"1.2.3" > "1.2.4" //false
"1.2.3" < "1.2.4" //true
Note, that none of these solutions will knowingly return the right result for things like 0.9beta or 1.0 RC 1. It is, however, handled quite intuitively in PHP: http://de3.php.net/manual/en/function.version-compare.php and there is a JS port of this: http://phpjs.org/functions/version_compare (I don't claim this to be very nice or efficient, just kind of 'complete').
Maybe like this (quickie)?
function isNewer(s0, s1) {
var v0 = s0.split('.'), v1 = s1.split('.');
var len0 = v0.length, len1=v1.length;
var temp0, temp1, idx = 0;
while (idx<len0) {
temp0 = parseInt(v0[idx], 10);
if (len1>idx) {
temp1 = parseInt(v1[idx], 10);
if (temp1>temp0) {return true;}
}
idx += 1;
}
if (parseInt(v0[idx-1], 10)>parseInt(v1[idx-1], 10)) {return false;}
return len1 > len0;
}
var version = "1.2.3";
var otherVersion = "1.2.4";
console.log('newer:'+(isNewer(version, otherVersion)));
It takes care of different number of parts, but it works only with numbers between the dots though.