Comparing values in Array fails - javascript

Sometimes comparing two strings within arrays fails. Failing occurs occasionally only in looped ifs. Example code below stands for implementing the problem.
searchTable.sort();
for(n=1;n<searchTable.length;n++){
// alert(searchTable[n-1]!=searchTable[n]);
if(searchTable[n-1]!=searchTable[n]){
idx++;
memTable[idx]=searchTable[n];
}
}
Values in the searchTable are strings for sure, and all values are not similar either.
In loop, all values are set in memTable[idx], despite of the similar values in [n-1] and [n]. Activated alert() shows the right comparison result, but if passes all through. Looks like the comparison in if is done by reference, not by value. How is this possible? Is this a bug in the JavaScript interpreter or what?
Action can be corrected by adding valueOf()-methods to both members in comparison expression. I've crashed this failier whithin looped ifs only. Sometimes it takes a long time to figure out why the code won't work.

You seem to have concluded that the problem is related to the actual data in the arrays. I suspect we can't help more specifically without seeing what that data is.
If putting valueOf() in front makes it work, then you can code a check for when the comparison with valueOf() is different than just straight != and output the two values to the debug console or break into the debugger so you can inspect what values are causing the problem. In other words, write code that catches the problem condition and allows you to inspect it.

Looks like you want to remove double values from an Array.
Try using:
var tmpObj = {}, resultArr = [];
for(n=1;n<searchTable.length;n++){
if (searchTable[n] in tmpObj){
continue;
}
tmpObj[searchTable[n]] = true;
}
for (var l in tmpObj){
resultArr.push(l);
}
Note: this will not differentiate between Numbers and Strings (so 1 equals '1')

Related

JavaScript Variable calls function, but stays undefined

I'm extremely new to JavaScript and am attempting to make a very simple game of 'Rock, Paper, Scissors' that is played through the console.
Here is a jsfiddle.net link to the full thing.
The main issue so far is that, every single round, the game will result in a Tie (another one is that incorrect inputs in humanTurn() lead to an error further down the line, but that's not relevant to this topic which I feel is more pressing).
Both humanTurn() and computerTurn() seem to work fine when called individually, however when called within gameRound(), the two console.log()'s (lines 36 and 38) don't seem to be returning a value of any kind, and in the console these show up as ƒ toLocaleUpperCase() { [native code] }. I tried searching for what this could mean, and the only conclusion I've been able to come up with so far is that no value is actually being stored inside of the two variables, AIChoice and HUChoice, and I cannot fathom a reason for why this would be happening.
Any and all help is greatly appreciated!
computerTurn().toLocaleUpperCase and userTurn().toLocaleUpperCase are both functions and since they are on the String prototype, they are both the same function. If you compare them, they will always be equal.
You need to actually call the function in order to get the values you want:
let AIChoice = computerTurn().toLocaleUpperCase();
console.log(AIChoice);
let HUChoice = humanTurn().toLocaleUpperCase();
console.log(HUChoice);

Javascript Nested For Loop Array has hidden value

I have been using javascript to run some simple code that uses the leaflet.js library (in this instance, the particular function is mymap.layerPointToLatLng(), here is the documentation ).
I want to use some data of the form [[[x,y]],[[x,y]],...] (the format is particular for how leaflet.js handles polygons and multipolygons, this kind of format is what I have called 'dim=2'). I need to convert it into latitudes and longitudes (hence the previously mentioned function). Because I do this a lot, I wrote a function to do it for me:
/*-Formatting functions*/
function coordconvert(mapvar,array,dim){
var temp1in=[],tempout1=[],temp2out=[];
if(dim===1){
for(i=0;i<array.length;i++){
tempout1[i]=mapvar.layerPointToLatLng(array[i]);
}
return tempout1;
}
else if(dim===2){
for(i=0;i<array.length;i++){
temp1in=array[i];//each polygon
console.log(i);
console.log(temp1in);
console.log(tempout1);
//tempout1=[];//why do I need this line?
for(j=0;j<temp1in.length;j++){
console.log(tempout1);
var checking = mapvar.layerPointToLatLng(temp1in[j]);
tempout1[j]=mapvar.layerPointToLatLng(temp1in[j]);//each vertex of polygon
console.log(j);
console.log(tempout1);
console.log(checking);
}
temp2out[i]=tempout1;//array of polygons
}
return temp2out;
}
else{
console.log("Unable to process coordinate conversion on array");
return
}
}
However, the 'if(dim===2)' section does not appear to be working correctly, hence all of the console.log lines.
In particular, the assignment tempout1[j]=mapvar.layerPointToLatLng(temp1in[j]); only appears to be working if I uncomment the line //tempout1=[];//why do I need this line?.
Using the console.log's, and viewed using Google Chrome, I get the following outputs:
First few iterations of loop
Final iteration of the loop
So as can be seen, The value (an object) of the final iteration is being included in the array of tempout1 before anything has been assigned to it (I have tried removing the 'if(dim===1)' section, and renaming the tempout1 variable, with no luck), and is being hidden by Chrome(?!?!?!); The value is not being over-written during the loop (as can be seen by the comparison of console.log(checking) and console.log(tempout1).
Why do I have to scrub the variable each time before the nested loop runs? And why is the value from the final iteration getting in before anything happens?
Turns out the solution was quite simple - I wasn't declaring the loop variables properly (i.e. for (var i=o;i<array.length;i++), rather than for (i=o;i<array.length;i++)) I'm not sure how this explains the behaviour of the Google Chrome console, but everything seemed much more stable afterwards.

"in" operator showing functions in javascript

in my code I was always doing
for(i in vector)...
and it always worked, but the problem is that it somehow changed and now my for shows all the values but also the properties, like "remove" that is a function, and it is breaking my whole code.
I don't know why it suddenly changed, because I didn't do anything and I'm getting crazy with this already.
Do you guys know what is happening with my application?
Another thing is that the code only get this problem on my computer.
If I clone my repository again and try it works for while but then starts the problem again.
Thank you.
The in operator has always had this behaviour. Just check that the property exists directly on the object instead of on the prototype:
for (var i in vector) {
if (vector.hasOwnProperty(i)) {
// Property exists on object
}
}
That should solve your issues.
Tom

How to create push a large number of string elements into array in javascript without error

I'm using the following function to take a large array of strings (user names) and check them for single quotes, then push them into my new array and return that.
Recently, the number of users in this list increased dramatically (7418 currently) and now this function is getting an error:
Caused by: java.lang.ClassFormatError: Invalid method Code length
105684 in class file org/mozilla/javascript/gen/c135516
The version of javascript is embedded in the application so upgrading that is not an option at this time.
Is there a better way to do this? or a different way to try to avoid this error?
function listExcludedUsers(rInactive) {
var result = new Array('user1', 'user2', 'user3', 'user4');
for (var i = 0; i < rInactive.length; i++) {
//replace single quote with two single quotes for DQL
if (rInactive[i].indexOf("'") > 0) {
rInactive[i] = rInactive[i].replace(/'/g, "''");
}
result.push(rInactive[i]);
}
return result;
}
Thhe JVM restricts the length of methods to 65536 bytes, so it seems as if you have found a bug in Mozilla. Please file it (with example if possible) at https://bugzilla.mozilla.org/.
Meanwhile: try to cut your method in multiple smaller parts, e.g.: chop the input and push it into several smaller arrays and concatenate those at the end. You should do it with several different functions.
This code looks like you are running a jvm that does not take very long methods name and those methods are because of the JavaScript input you are giving, it would be nice to try to reproduce the case, I would
Try to change the input of your JavaScript code that makes those methods in jvm too longs, may be in several sets of inputs.

JavaScript string comparison fails randomly

I’m having a pretty weird bug occurring in my JS application on a random basis. Basically, the script fails to accurately compare two strings. More specifically, at times does not see two identical strings as identical: ('blah' == 'blah') returns false.
The funny thing is that on another try, the same two strings may be admitted to be identical (statement returns true). I never managed to figure out the pattern. I’ve also tried to use === instead of ==; this didn’t help.
I couldn’t think of a better way to demonstrate and prove this ridiculous bug other than by recording a screencast. So here it is: http://www.screenr.com/klOs. I keep giving correct answers for each quiz in that video, but closer to the end you will how my answers for ‘Japan’ and ‘Taiwan’ will be regarded as ‘wrong’; the console will also show the given answer string, the correct answer string, and the result of their comparison (false ?!!).
So what could possibly be the reason for this odd behaviour and how do I get around fixing it?
You can see the code with the comparison statement in the screencast. The ‘params.givenAnswer’ comes directly from the button text label:
//*** Options for answering the card quiz
quizOptions = new Ext.Panel({
id: 'quizOptions',
[…………]
listeners: {
el: {
scope: this,
tap: this.checkAnswer
}
}
});
checkAnswer: function(container, element) {
// Get the text value of the button clicked
var answer = Ext.fly(element).dom.innerText;
Ext.dispatch({
controller: 'Practice',
action: 'checkAnswer',
givenAnswer: answer
});
},
UPDATE Thank you #JAAulde and #Mike! I’ve tried to include the quotes and the var type in the logging and I got this result:
Now it’s clear why the string comparison fails: there seem to be an extra line break of sorts in the first string. It’s still very weird, since it didn’t not appear as a blank new line in the previous logging, and most importantly, it appears there randomly (notice how ‘Taiwan’ was accepted this time without any problems).
I’ve included a simple line-break removal rule for the answer strings, and now everything seem to be working fine. Thanks a lot everyone!
Using === is a strict equality comparison. This means that the data type and the contents are being compared. They both (data and type) must be the same to equal and return true.
When you switched your strict comparison to == the test should have worked even though the data types were different. It failed however because of the extra blank spaces.

Categories

Resources