Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript indexOf not working as expected with array

Tags:

I am getting -1 from myarray.indexOf(element) even when element appears to be in myarray.

Here's some code snippets:

function createChangeRecord( old_array, new_array ) {     var nds = new_array.slice(0,new_array.length);     var el, idx;     if (...) {         ...     } else if ( old_array.length==new_array.length ) {         for ( var i=0; i<old_array.length; i++ ) {             el = old_array[i];             idx = nds.indexOf(el);             if ( idx!=(-1) ) {                 ...             } else {                 var a = "el: " + el + "; nds: " + nds + "; nds.indexOf(el): " + nds.indexOf(el);                 alert( a );                 ...             }         }         ...     }     ... } 

The alert shows me that nds does indeed contain el but the alert should only fire when idx==-1, which should only be true when nds does not contain el.

I know I haven't given enough information to determine the specific issue in my case, but maybe someone can tell me some general reasons which might cause this behavior?

Responses to a similar question suggested using jQuery inArray() instead of indexOf, but I want to know why indexOf doesn't work. Others suggested that indexOf is for strings, not arrays, but that's not true from the online docs I can find.

like image 855
baixiwei Avatar asked Jan 08 '13 19:01

baixiwei


People also ask

How to find the index of an array in JavaScript?

JavaScript findIndex () Method: This method returns the index of the first element in an array that satisfies the condition. If this method finds an array element for which the function returns a true value, this method returns the index of that array element and stops, Otherwise, it returns -1. cValue: This parameter is required.

Does indexOf() work with array?

Yes, indexOf () works with array (of number, string, or any object), as well as with string. But you have to make sure to check with same types. What does parseInt () do? To avoid unintended comparison of a number with a string, we can use parseInt (), for example parseInt ("123", 10) returns the number 123. The second argument 10 is called radix.

Why does indexOf() not work with string?

Because "100" string is not same as 100 number. Does indexOf () work with strings, array, etc? Yes, indexOf () works with array (of number, string, or any object), as well as with string. But you have to make sure to check with same types. What does parseInt () do?

Why does indexOf return -1 in JavaScript?

In many cases JavaScript performs conversions automatically when they are needed. For example, if you add a number to an item that consists of text (a string), the number is converted to text. And I guess such conversion was the reason of indexOf returning -1 because one of your array contained number and other contained string.


1 Answers

Use

nds.indexOf(parseInt(el,10))  

where nds is an array and el is a number (or supposed to be a number)

Edit:

From msdn:

JavaScript is a loosely typed language, which means you do not declare the data types of variables explicitly. In many cases JavaScript performs conversions automatically when they are needed. For example, if you add a number to an item that consists of text (a string), the number is converted to text.

And I guess such conversion was the reason of indexOf returning -1 because one of your array contained number and other contained string.

For example:

old_array = ["10", "20", "30"]; new_array = [10, 20, 30]; 

Below is my attempt to answer your questions:

Why indexOf() does not work?

It does work and I guess it worked in your case too. It returned -1 when el string, e.g "100", was not found in an array of numbers, e.g. nds=[100,200] which is true. Because "100" string is not same as 100 number.

Does indexOf() work with strings, array, etc?

Yes, indexOf() works with array (of number, string, or any object), as well as with string. But you have to make sure to check with same types.

What does parseInt() do?

To avoid unintended comparison of a number with a string, we can use parseInt(), for example parseInt("123", 10) returns the number 123.

The second argument 10 is called radix. A number (from 2 to 36) that represents the numeral system to be used.

Summary:

> "javascript is awesome".indexOf('v') 2 > [10, 20, 30].indexOf("20") -1 > [10, 20, 30].indexOf(20) 1 > [10, 20, 30].indexOf( parseInt("20", 10) )  1 > typeof (100) number > typeof ("100") string > typeof( parseInt( "100", 10)) number > parseInt( "100", 10) 100 > parseInt("100", 2) 4 > parseInt(11.3, 10) 11 > parseInt(11.3, 2) 3 > [10.3, 11.3, 12.3, 11].indexOf( parseInt(11.3, 10) ) 3 

To see all of above in action:

check the below code snippet but be aware of alert(); and console.log(); when you run it.

function createChangeRecord( old_array, new_array ) {        var nds = new_array.slice( 0, new_array.length ); // this seems to be redundant      var el, idx, msg;            if ( old_array.length == new_array.length ) {          for ( var i=0; i<old_array.length; i++ ) {                el = old_array[i];              idx = nds.indexOf(el);                if ( idx != -1 ) {                  msg = "Found: el: " + el + "; nds: " + nds + "; nds.indexOf(el): " + idx + "\n typeof el: " + (typeof el) + "; typepf nds[" + i + "]: " + (typeof nds[i]);              } else {                  msg = "Not Found: el: " + el + "; nds: " + nds + "; nds.indexOf(el): " + idx + "\n typeof el: " + (typeof el) + "; typepf nds[" + i + "]: " + (typeof nds[i]);              }                console.log( msg );              alert( msg );          }      }      else {          var err = 'Array lengths are not same';          console.log( err );          alert( err );      }  }    // this will work  var old_array_g = [ 10, 20 ];  var new_array_g = [ 10, 20 ];  createChangeRecord( old_array_g, new_array_g );    // this will not work  var old_array_g = [ "10", "20" ];  var new_array_g = [ 10, 20 ];  createChangeRecord( old_array_g, new_array_g );    // Yes: indesOf works with strings too    var withStrings = "'javascript is awesome'.indexOf('v'): " + "javascript is awesome".indexOf('v');  console.log( withStrings );  alert( withStrings );      // parseInt() returns a number or say integer  var usingParse = "typeof(123): " + typeof( 123 ) + "; typeof( parseInt('123', 10) ): " + typeof ( parseInt('123', 10) ) + "; typeof ('123'): " + typeof('123');  console.log( usingParse );  alert( usingParse );    // parseInt() with base 2  var parseBase2 = "parseInt( '100', 2 ): " + parseInt('100', 2) + "; parseInt( '100' , 10): " + parseInt('100', 10);  console.log( parseBase2 );  alert( parseBase2 );
like image 152
Ajeet Shah Avatar answered Nov 16 '22 23:11

Ajeet Shah