Find element in Javascript Array [duplicate] - javascript

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Javascript - array.contains(obj)
What's wrong with this:
var zipCodes =(['90001','90002','90003']);
Test if the value exists in the array zipCodes
if('90001' in zipCodes) {
alert('True');
};

The in operator looks at property names, not values.
Because it's an Array, the property names will be the indices of the Array.
If you're only supporting a modern environment, you could use Array.prototype.indexOf().
if(zipCodes.indexOf('90001') > -1) {
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;
};
}

If you want to check if the array contains a given value, you can use the indexOf method to check for the position of an item. If the item is not found in the array, a -1 is returned:
var zipCodes =(['90001','90002','90003']);
zipCodes.indexOf('90001') // 0
zipCodes.indexOf('90002') // 1
zipCodes.indexOf('90003') // 2
zipCodes.indexOf('90004') // -1
if(zipCodes.indexOf('90001') != -1) {
alert('True');
};
See more at http://freewebdesigntutorials.com/javaScriptTutorials/jsStringObject/indexOfMethod.htm

Use an object instead. If this is all you're trying to do with the array, then an object is a much more efficient way to do a lookup list.
var zipCodes = {"90001": true, "90002": true, "90003": true};
if ('90001' in zipCodes) {
alert('True');
}
jsfiddle here to see it work: http://jsfiddle.net/jfriend00/ZNGTq/

You need something like this:
var zipCodes =(['90001','90002','90003']);
if (zipCodes.has('90001')) {
....
}
Array.prototype.has=function(v){
for (i=0;i<this.length;i++){
if (this[i]==v) return i;
}
return false;
}
See this for more info:
http://snook.ca/archives/javascript/testing_for_a_v
....

Because in checks for a property of an object. Check this out for converting "in object" to "in array": Testing for a Value in JavaScript Array

Related

How to fix 'indexof' in IE8 [duplicate]

The below function works fine on Opera, Firefox and Chrome. However, in IE8 it fails on the if ( allowed.indexOf(ext[1]) == -1) part.
Does anyone know why? Is there any obvious mistake?
function CheckMe() {
var allowed = new Array('docx','xls','xlsx', 'mp3', 'mp4', '3gp', 'sis', 'sisx', 'mp3', 'wav', 'mid', 'amr', 'jpg', 'gif', 'png', 'jpeg', 'txt', 'pdf', 'doc', 'rtf', 'thm', 'rar', 'zip', 'htm', 'html', 'css', 'swf', 'jar', 'nth', 'aac', 'cab', 'wgz');
var fileinput=document.getElementById('f');
var ext = fileinput.value.toLowerCase().split('.');
if ( allowed.indexOf(ext[1]) == -1)
{
document.getElementById('uploadsec').innerHTML = document.getElementById('uploadsec').innerHTML;
alert('This file type is not allowed!');
}
}
Versions of IE before IE9 don't have an .indexOf() function for Array, to define the exact spec version, run this before trying to use it:
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
This is the version from MDN, used in Firefox/SpiderMonkey. In other cases such as IE, it'll add .indexOf() in the case it's missing... basically IE8 or below at this point.
If you're using jQuery, you can use $.inArray() instead.
If you're using jQuery and want to keep using indexOf without worrying about compatibility issues, you can do this :
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(val) {
return jQuery.inArray(val, this);
};
}
This is helpful when you want to keep using indexOf but provide a fallback when it's not available.
For a really thorough explanation and workaround, not only for indexOf but other array functions missing in IE check out the StackOverflow question Fixing JavaScript Array functions in Internet Explorer (indexOf, forEach, etc.)
Please careful with $.inArray if you want to use it.
I just found out that the $.inArray is only works with "Array", not with String.
That's why this function will not working in IE8!
The jQuery API make confusion
The $.inArray() method is similar to JavaScript's native .indexOf()
method in that it returns -1 when it doesn't find a match. If the
first element within the array matches value, $.inArray() returns 0
--> They shouldn't say it "Similar". Since indexOf support "String" also!
The problem
IE<=8 simply doesn't have an indexOf() method for arrays.
The solution
If you need indexOf in IE<=8, you should consider using the following polyfill, which is recommended at the MDN :
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return -1;
}
var n = +fromIndex || 0;
if (Math.abs(n) === Infinity) {
n = 0;
}
if (n >= len) {
return -1;
}
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
while (k < len) {
if (k in o && o[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
Minified :
Array.prototype.indexOf||(Array.prototype.indexOf=function(r,t){var n;if(null==this)throw new TypeError('"this" is null or not defined');var e=Object(this),i=e.length>>>0;if(0===i)return-1;var a=+t||0;if(Math.abs(a)===1/0&&(a=0),a>=i)return-1;for(n=Math.max(a>=0?a:i-Math.abs(a),0);i>n;){if(n in e&&e[n]===r)return n;n++}return-1});
You can use this to replace the function if it doesn't exist:
<script>
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(elt /*, from*/) {
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0) ? Math.ceil(from) : Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++) {
if (from in this && this[from] === elt)
return from;
}
return -1;
};
}
</script>

jQuery TypeError: includes is not a function in firefox [duplicate]

right here is a block of my code. It works perfect in fireFox and Chrome. But not in IE. I get the error "Object doesn't support property or method 'includes'"
function rightTreeSwapfunc2() {
if ($(".right-tree").css("background-image").includes("stage1") == true) {
$(".right-tree").css({
backgroundImage: "url(/plant-breeding/img/scenes/plant-breeding/stage5.jpg)"
})
} else {
$(".right-tree").css({
backgroundImage: "url(/plant-breeding/img/scenes/plant-breeding/stage3.jpg)"
})
}
}
I could change it up a bit and use vanilla JS and do:
document.getElementById("right-tree").classList.contains
But I would rather see if there is a way to get it to work in IE before changing the JS and editing the HTML and CSS.
If you look at the documentation of includes(), most of the browsers don't support this property.
You can use widely supported indexOf() after converting the property to string using toString():
if ($(".right-tree").css("background-image").indexOf("stage1") > -1) {
// ^^^^^^^^^^^^^^^^^^^^^^
You can also use the polyfill from MDN.
if (!String.prototype.includes) {
String.prototype.includes = function() {
'use strict';
return String.prototype.indexOf.apply(this, arguments) !== -1;
};
}
IE11 does implement String.prototype.includes so why not using the official Polyfill?
Source: polyfill source
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}
In my case i found better to use "string.search".
var str = "Some very very very long string";
var n = str.search("very");
In case it would be helpful for someone.
Here is solution ( ref : https://www.cluemediator.com/object-doesnt-support-property-or-method-includes-in-ie )
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function (searchElement, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
// 1. Let O be ? ToObject(this value).
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.
if (sameValueZero(o[k], searchElement)) {
return true;
}
// c. Increase k by 1.
k++;
}
// 8. Return false
return false;
}
});
}
import 'core-js/es7/array'
into polyfill.ts worked for me.

How to get the max occurrences of a number in an array

as answer to an exercise in which I had to create a function that given an array of numbers return the number with most occurrences, and if more than one number had the max number of occurrences return the minor one. This is the implementation I made, but I'm pulling my hair figuring out why it return 10 instead of 9 in the example.
It appears to be evaluating 10 < 9 as true. What's wrong?
function maxOccurencies(arr) {
var aux = [], max = 0, final = null;
for (var i=0,t=arr.length; i<t; i++) {
aux[arr[i]] = (aux[arr[i]] || 0) + 1;
if (aux[arr[i]] > max) max = aux[arr[i]];
}
for (x in aux) {
if ( aux[x] == max && (x < final || final == null)) {
final = x;
}
}
return final;
}
document.write(maxOccurencies([10,10,10,9,9,9,8,7,4,5,1]));
Putting typeof(x) in your second loop reveals that some of your variables are being cast as type string! Still looking into exactly where this is occurring. You can replace
if ( aux[x] == max && (x < final || final == null)) {
with
if ( aux[x] == max && (parseInt(x) < parseInt(final) || final == null)) {
to return the correct value of 9.
Edit:
Very interesting, I was unaware of Javascript's exact handling of arrays in for...in loops. See the following other questions for more information:
JavaScript For-each/For-in loop changing element types
Why is using “for…in” with array iteration such a bad idea?
Also note that you can use arr.forEach(function(element){...}); and the elements are returned with their types intact.
I think the problem is just that the x in aux is not a number so the if statement isn't evaluating correctly. when converted to a number then it returns 9 (below).
(3 == 3 && ("10" < "9" || "9" == null)) evaluates to true
function maxOccurencies(arr) {
var aux = [], max = 0, final = null;
for (var i=0,t=arr.length; i<t; i++) {
aux[arr[i]] = (aux[arr[i]] || 0) + 1;
if (aux[arr[i]] > max) max = aux[arr[i]];
}
for (x in aux) {
if ( aux[x] == max && (parseInt(x) < final || final == null)) {
final = parseInt(x);
}
}
return final;
}
document.write(maxOccurencies([10,10,10,9,9,9,8,7,4,5,1]));
"I'm pulling my hair figuring out why it return 10 instead of 9 in the example."
That's because in this sort of comparison, 10 is smaller than 9,8,7,6,5,4,3, 2 but a bit grater than 1.
:)
This small type correction will fix it:
function maxOccurences(arr) {
aux = [], max = 0, final = null;
for (var i=0,t=arr.length; i<t; i++) {
aux[arr[i]] = (aux[arr[i]] || 0) + 1;
if (aux[arr[i]] > max) max = aux[arr[i]];
}
for (x in aux) {
if ( aux[x] == max && (+x < final || final == null)) {
final = x;
}
}
return final;
}

Which indexOf function should I use?

I've encountered this code in a codebase to add the indexOf function :
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
This is a different implementation to the one recommended by Mozilla https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf :
Code:
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;
}
}
Should I be using the Mozilla version instead or will version mentioned at beginning of question suffice ? Are there advantages of using one over the other ?
They're both from MDN but the first version is from an older version of the indexOf page. The newer version is an update to bring the implementation in line with the algorithm published in the ECMAScript 5 spec. Given all that, it seems reasonable to use the newer version.
Here's the diff on the MDN page where the change was made:
https://developer.mozilla.org/index.php?title=en/JavaScript/Reference/Global_Objects/Array/indexOf&action=diff&revision=32&diff=33
I'd suggest using Mozilla version on indexOf. It's quite similar to the first implementation, but is more polished (which is not surprising, actually). For example, it will return -1 right as it finds out that given array is empty, and will correctly process different edge values given as a second parameter.
Or better yet, if you use jQuery (as it is implied by your tags choice), why don't just use its $.inArray() method?

indexOf is not a function in Firefox, Opera but works in IE, indexOf alternative in javascript to test string contains?

Getting an error using indexOf call in Javascript on Firefox and Opera. Works fine in IE.
Following is the error message:
Action
function anonymous(Grid, Row, Col, Event) {
return Grid.ActionShowPopupMenu();
}
for event OnRightClick failed with exception: row.id.indexOf is not a function
I'm testing that a string contains another string in Javascript and using the indexOf function of a string. The calls however are being made in JQuery functions. Perhaps that is the reason for the problem? Is there an alternative to using indexOf in Javascript to test if a string contains another string? Is there a workaround for this problem?
String.indexOf is perfectly OK in all browsers. I assume the id property of your row object is no string (nor array, btw, because indexOf is also defined on arrays (except for IE))
indexOf is not okay for IE prior to IE9. If you want your code to work in ie < 9, you should define the method for non-compliant browsers in a common js file that can be dropped into every page. See this thread for more details. The code is taken from Mozilla
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;
}
}
indexOf() is ok for all browsers. It is designed for both, String and Array, see this: http://jsfiddle.net/SquTp/
There is maybe something wrong with your dom selection, or you may use it in the wrong way.

Categories

Resources