This is gonna be a bit of a weird one b/c I can't provide the actual input for the test case. On the codingGame website there is an exercise where I have to find the lowest difference between integers. I create a variable, but leave it undefined and later use it to hold the lowest difference
function shortest(horses){
let short;
horses.sort((a,b) => a - b).forEach((horse,i) => {
let dif = horse - horses[i-1];
if (dif < short || !short) short = dif;
});
return short;
};
This passes all the tests but one, and the only way to solve the failed one is to assign a value to short instead of leaving it undefined (like let short = 10000000000000);
The website, annoyingly, won't give out the input so I'm not sure why the code is behaving this way so does does anyone know why leaving it undefined instead of a value will cause problems?
Related
This is from Leetcode problem: Concatenated Words.
Below is a working solution. I added what I thought to be an optimization (see code comment), but it actually slows down the code. If I remove the wrapping if statement, it runs faster.
To me, the optimization helps avoid having to:
call an expensive O(n) substring()
check inside wordsSet
making an unnecessary function call to checkConcatenation
Surely if (!badStartIndices.has(end + 1)) isn't more expensive than all the above, right? Maybe it has something to do with Javascript JIT compilation? V8? Thoughts?
Use the following test input:
// Notice how the second string ends with a 'b'!
const words = [
'a',
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab',
];
// Function in question.
var findAllConcatenatedWordsInADict = function (words) {
console.time();
// 1) put all words in a set
const wordsSet = new Set(words);
let badStartIndices;
// 2) iterate words, recursively check if it's a valid word
const concatenatedWords = [];
function checkConcatenation(word, startIdx = 0, matches = 0) {
if (badStartIndices.has(startIdx)) {
return false;
}
if (startIdx === word.length && matches >= 2) {
concatenatedWords.push(word);
return true;
}
for (let end = startIdx; end < word.length; end++) {
// I ADDED THE IF STATEMENT AS AN OPTIMIZATION. BUT CODE RUNS FASTER WITHOUT IT.
// NOTE: Code is correct with & without if statement.
if (!badStartIndices.has(end + 1)) {
const curWord = word.substring(startIdx, end + 1);
if (wordsSet.has(curWord)) {
if (checkConcatenation(word, end + 1, matches + 1)) {
return true;
}
}
}
}
badStartIndices.add(startIdx);
return false;
}
for (const word of words) {
// reset memo at beginning of each word
badStartIndices = new Set();
checkConcatenation(word);
}
console.timeEnd();
return concatenatedWords;
};
Turns out this depends entirely on the input data, not on JavaScript or V8. (And as of writing this, I don't know what data you used for benchmarking.)
With the example input from the Leetcode page you've linked, badStartIndices never does anything useful (both of the .has checks always return false); so it's fairly obvious that doing this fruitless check twice is a little slower than doing it just once. In that case, the "dynamic programming" mechanism of the solution never kicks in, so the effective behavior degenerates to brute force, which is good enough because the input data is well-behaved. (In fact, deleting badStartIndices entirely would be even faster for such a test case.)
If I construct "evil" input data that actually leads to exponential combinatorial blow-up, i.e. where the badStartIndices.has(...) checks actually have something to do, then adding the early check does have a (small) performance benefit. (And without either of the checks, the computation would take "forever" for such inputs.)
So, taking a step back, this is one more example to illustrate that benchmarking is difficult; in particular, in order to get useful results, care must be taken to select relevant/realistic input data.
If the tests are too simple, developers are likely to not build optimizations that would help (a little or a lot) in high-load situations.
If the tests are too demanding, developers are likely to waste time on overly complicated code that ends up being slower than it could be for its target use case.
And if the code must handle any input with maximum performance, then as the developer you have the extra challenge of avoiding overhead for simple inputs while still scaling well to tough inputs...
function upgrade(cost, hps, htmlName, id)
{
/* calc new cost based on quantity currently has */
var currUpgradeCost = Math.floor(cost * Math.pow(1.1,upgradeCount[id]));
/* can they afford it? */
if(totalHacks >= currUpgradeCost)
{
/* tally up THIS UPGRADE */
upgradeCount[id]++;
/* total the upgrades as a whole */
totalUpgrades = totalUpgrades + hps;
/* subtract this cost fro the total hacks so far */
totalHacks = totalHacks - currUpgradeCost;
/* update the HTML */
document.getElementById('hpc').innerHTML = totalUpgrades.toFixed(1);
document.getElementById('totalHacks').innerHTML = totalHacks.toFixed(0);
};
/* calc/display cost for next upgrade */
var nextCost = Math.floor(cost * Math.pow(1.1,upgradeCount[id]));
document.getElementById(htmlName).innerHTML = nextCost;
};
<button onclick="upgrade(15, .1,'upgradePCCost', 0)">Upgrade System</button>
- Cost <span id="upgradePCCost">15</span><br/>
<button onclick="upgrade(100, .5,'scriptBotCost', 1)">Script Bot</button>
- Cost <span id="scriptBotCost">100</span><br/>
EDIT: FULL FUNCTION:(yes tinkering with a clicker game to learn JS. )And I'll take the negative votes if it will solve it. These are the two sections giving me issues.
/EDIT
OK, hope I made this simple and to the point. Main problem - it works, it just gives a NaN error for the targetId.
Now I've been reading everywhere, and a couple things I found.
I could not find anyone passing a var to the elementById in the manner I was.
Since I cannot find the answer that works - I am obviously doing it wrong.
This is all part a larget project, and to avoid redundant code, it is based on what button they are clicking, so I just add that to the function. The only line that does not work, is the one above: elementById. My debugger does not show any errors, the html just keeps spitting out a NaN instead of 444 (in this example)
Many of the sites / forums I checked, all say this should work. So there is something I am missing.
Couple of the things I've tried:
-.toString()
-elementsByName
Thanks. I am pretty sure I checked everywhere on S.O. to make sure this is not a dupe, as no one is doing the same thing with the same results (i.e. many I found were solved because of typos - obviously, that is not my issue)
if this code doesn't work for you, definitely related with other part of your code. document.getElementById function expects string as argument, and you pass one, so, i don't think it's the problem. Similarly, you assign string to innerHTML property takes also string, but passing number value doesn't hurt, because javascript converts it to string for you. So, the error you get NaN (not a number) has nothing to do with the line:
document.getElementById(htmlName).innerHTML = someVar;
I don't see the other part of your code as you trimmed out, but I suspect the function runs when you click on the button, is reading the value "444" in your example, and passing to your "myFunction". Probably you should look for error there.
Ask yourself the classical debugger question when you stuck, what justifies my expectation the things to be as the way I expected? And find the line in your code justifies your expectation and check if it runs the way it should?
Using your example, you pass a "number" to innerHTML property, any you get NaN error. So, the question is, what justifies that the number you pass is a number? And find that part of your code, if you pass a number.
UPDATE: After seeing other part of your code, it looks your nextCost variable is NaN, so you cannot assign it to innerHTML.
nextCost is using some math calculation, which involves cost, which is number, considering onClick calls, only thing remains is the upgradeCount[id] array/object, both can be, but probably array. So I think you should look still other part of your code, which forms upgradeCount array, and make sure that upgradeCount in index id has number value.
Hope it helps.
This works perfectly for me:
<button onclick="upgrade(15, .1,'upgradePCCost', 0)">Upgrade System</button>
- Cost <span id="upgradePCCost">15</span><br/>
<button onclick="upgrade(100, .5,'scriptBotCost', 1)">Script Bot</button>
- Cost <span id="scriptBotCost">100</span><br/>
<script type="text/javascript">
function upgrade(cost, hps, htmlName, id)
{
upgradeCount = [ 1, 2, 3, 4 ];
totalHacks = 0;
/* calc new cost based on quantity currently has */
var currUpgradeCost = Math.floor(cost * Math.pow(1.1,upgradeCount[id]));
/* can they afford it? */
if(totalHacks >= currUpgradeCost)
{
/* tally up THIS UPGRADE */
upgradeCount[id]++;
/* total the upgrades as a whole */
totalUpgrades = totalUpgrades + hps;
/* subtract this cost fro the total hacks so far */
totalHacks = totalHacks - currUpgradeCost;
/* update the HTML */
document.getElementById('hpc').innerHTML = totalUpgrades.toFixed(1);
document.getElementById('totalHacks').innerHTML = totalHacks.toFixed(0);
};
/* calc/display cost for next upgrade */
var nextCost = Math.floor(cost * Math.pow(1.1,upgradeCount[id]));
document.getElementById(htmlName).innerHTML = nextCost;
};
</script>
I've run your code, and as you can see. If all the values are correct this function should work. As you can see i added upgradeCount and totalHacks so i could make the code run. But remember, before you can do math on the array you must be sure that all the values in it, is numbers, else you will get NaN.
I was trying to crawl a very old website for a specific tag, I need to get it by it's for= attribute. So I used this piece of code.
var character = document.querySelectorAll("label[for=char_1]");
For some reason it returns an undefined, but I was using this script for a few days now and it worked like a charm. Here's the fun part. Typing that command in browsers console will result in undefined. But typing this alone:
document.querySelectorAll("label[for=char_1]");
Will return a proper NodeList. Why it won't assign to a variable...?
edit: It seems that deleting var and typing character without it will make it work. It's resolved but I would still love to get an answer to "why is this happening"?
edit2:
for (var i = 0; i < 15; i++) {
var character = document.querySelectorAll("label[for=char_" + i +"]");
console.log(character); // this will return [] from the script.
var color = character[0].children[0].style.color;
}
A simple for loop. All I get is Cannot read property 'children' of undefined. But I can type in the very same command document.querySelectorAll... and it will work in the browser and will return NodeList.
I had it working like this in a very hacky script. It worked.
var character1 = document.querySelectorAll("label[for=char_1]");
var characterColor1 = character1[0].children[0].style.color;
edit3:
var character1 = document.querySelectorAll("label[for=char_1]");
var characterColor1 = character1[0].children[0].style.color;
var character2 = document.querySelectorAll("label[for=char_2]");
var characterColor2 = character2[0].children[0].style.color;
// ...
The above code works without a single problem though. I don't think it's DOM not being ready as this code is also run from Greasemonkey script and it works. The only difference is the for loop.
var x = ""; // returns undefined, because it's a var assignment.
var elements = document.querySelectorAll('div');
That's expected behavior when pasted into the console.
edit: It seems that deleting var and typing character without it will make it work. It's resolved
I'm afraid you're creating a global scope variable now. or perhaps characters is an already defined variable in that scope.
Buhah, as I said in edit 3 "the only difference is the for loop". I was so busy trying to find an answer in the DOM-related things that I made the simplest mistake ever done in programming.
See?
char_1
With...
for(var i = 0...)
0! And I was testing char_1 in the browser instead of char_0. Which - truly - returns [] instead of something useful. Time to go on a holiday break I guess, my brain seems to be there already. :)
I'm using the following code to compare returned IP address (Using node-restify which is similar to express):
var checkIP = function (config, req) {
var ip = req.connection.remoteAddress.split('.'),
curIP,
b,
block = [];
for (var i=0, z=config.ips.length-1; i<=z; i++) {
curIP = config.ips[i].split('.');
b = 0;
// Compare each block
while (b<=3) {
(curIP[b]===ip[b] || curIP[b]==='*') ? block[b] = true : block[b] = false;
b++;
}
// Check all blocks
if (block[0] && block[1] && block[2] && block[3]) {
return true;
}
}
return false;
};
config.ips contains an array which (as should be obvious from the code) can be specific or wildcarded IPs.
This works, but it seems like there is a more efficient way to do this. Just curious if anyone has any suggestions on a way to simplify this or make it more efficient. My request time nearly doubled when I introduced this and I'd like to squeeze out some load time if possible.
If my intuition is correct, you might be doing a bunch of extra work right now:
For each IP expression in your config.ips array, your code is parsing and comparing:
if (block[0] && block[1] && block[2] && block[3]) {
return true;
}
^^^ Note that you have already done work to get all 4 blocks in the iterations of calculating this expression 4 times per IP: (curIP[b]===ip[b] || curIP[b]==='*'), so the ANDing above is not preventing the overhead of the work that is already happening regardless.
I have 2 ideas for you:
Since IP addresses are strings anyways, the * notation lends itself to be suitable for a Regex to do the work, instead of your splitting and comparing? So maybe as a next step you could look into implementing a Regex to do the work, instead of .split() and compare, and test the performance of that?
Or maybe figure out how to avoid that overhead associated with comparing the parts all the time, and compare the wholes when you can? And then fall back into comparing the parts only when necessity requires it.
If you want to read some C code, here's how Apache does IP blacklisting behind the scenes. Look at the function named in_domain for some inspiration.
Good luck, hope this helps!
Well my short and easy to explain explanation can be this. I have 2 arrays, FilterList and GamesReset. Whenever this function I have works and filters out some games with check boxes and a drop down menu, the function starts off with something like FilterList=GamesReset;. This functions seems to work fine until I filter out ages for the game. The function never touches GamesReset unless it's something like while(i<GamesReset.length){} or FilterList=GamesReset;. And the only tool I use when I filter games is FilterList.splice(i,1);. Now with that, GamesReset definitely, should never change as far as I know. I have it to reset FilterList, then depending on what needs to be filtered out, it will start removing those games from the FilterList. The problem I have, is that, GamesReset also becomes filtered. Which, does not make any sense at all. So like my title, it's just like saying b=0;, a=b;, a++;, and now b equals 1.
Now, I think that's the best/shortest way I can reveal this problem, without overdoing it with my bad habit of explaining things to people. I have a webpage currently available if anyone would like to see whats going on in action, because I wouldn't get what's going on with GamesReset either if I were you, here (url removed, read edit). To get the error working, just change the age to 10 without checking any boxes. The bottom paragraph is the GamesReset array (using <br> to separate each array), and it's the one that changes when I'm only changing FilterList in the JavaScript. The actual codes if you view the page source may be a little off compared to when I mentioned above, but it's pretty much 100% the same thing. I also wanted to have the codes available without a url and on this page, but I can't figure out how to do that with the html tags included.
Actually, here's the JavaScript function. I just figured out the 4 spaces thing when my question was rejected.
function SearchFilter() {
Games = GamesReset;
plat = document.getElementById('platformcheck').checked;
rpg = document.getElementById('rpgcheck').checked;
puzz = document.getElementById('puzzlecheck').checked;
hybo = document.getElementById('hybocollectcheck').checked;
ages = document.getElementById('agescheck').value;
if ((!plat) && (!rpg) && (!puzz) && (!hybo)) {
FilterList = Games;
} else {
FilterList = [];
i = 0;
while (i < Games.length) {
Set = '';
Set = Games[i];
Set = Set.split('</>');
StrFind = Set[0];
if (
(plat && (StrFind.search(',platform,') > -1)) || (rpg && (StrFind.search(',rpg,') > -1)) || (puzz && (StrFind.search(',puzzle,') > -1)) || (hybo && (StrFind.search(',hybocollect,') > -1))) {
FilterList.push(Games[i]);
}
i++;
}
// so by now, we should have the filtered array
}
//seperate filter for ages
i = 0;
while (i < FilterList.length) { //The problem should definitely start here
Set = '';
Set = FilterList[i];
Set = Set.split('</>');
StrFind = Set[1];
if ((Math.abs(StrFind)) > ages) {
FilterList.splice(i, 1);
} else {
i++;
}
}
GL.innerHTML = GamesReset.join('<br>');
}
As a reminder, the problem starts when the age filter is working. And the only thing it does is FilterList.splice(i,1);. But it ends up changing GamesReset. I changed this function a bit when I added Games=GamesReset;, but that was another test to try and make sure GamesReset doesn't get filtered like FilterList, but it still does.
EDIT: I removed my url since the answers definitely explained everything, so there's no need for it now.
Arrays are not copied when assigned, both variables will refer to the same data. Here is a post that goes into detail on this: Copying array by value in JavaScript
It makes perfect sense since variables are just references to objects in memory. One object can have several references. Consider this:
var a = { foo: 'bar' };
var b = a;
// b is now a reference to a and they both point to the same object
b.foo = 'doe';
alert( a.foo ); // alerts doe
The same goes for arrays. So when you do FilterList = GamesReset you are not copying the array - you are just assigning the same array to another variable. Any mutations or changes made to either reference will be reflected in all references.
To create a copy of an array you can use slice:
FilterList = GamesReset.slice();