Having trouble with a for loop not iterating enough - javascript

So I have a problem with this FOR loop that I just can't quite figure out. In this case, I know this needs to iterate as least twice. The array, at a minimum, looks something like this...
dTrackerArray = {sParentValue, 1234, sParentValue, 5678}
But for some reason this for loop is only removing one instance instead of all of them.
var check = $.inArray(sParentValue, dTrackerArray);
if (check != -1) {
for(var i = dTrackerArray.length; i > 0; i--) {
if( dTrackerArray[i] === sParentValue ) {
dTrackerArray.splice(i,1);
dTrackerArray.splice(i-1,1);
}
}}
I really appreciate any help I can get here! Thanks!
EDIT: The 2nd splice is to remove the 1234 "associated" with the sParentValue. It seems to work ok.

The problem is in for loop. you start from: var i = dTrackerArray.length and take dTrackerArray[i] this element does not exist. More over you forgot to interate with 0 index element. So you have to change your for loop to:
for(var i = dTrackerArray.length-1; i >= 0; i--)

Easy to miss but you need i >= 0.
EDIT:
Although I think your main issue is that you're modifying an array while your looping. Obviously with my fix you'll get an out of bounds error on the second splice.
var check = $.inArray(sParentValue, dTrackerArray);
if (check != -1) {
for(var i = dTrackerArray.length; i >= 0; i--) {
if( dTrackerArray[i] === sParentValue ) {
dTrackerArray.splice(i,1);
dTrackerArray.splice(i-1,1); //when i == 0 then exception
}
}}
Since you know the format of the array you can do this with a while loop:
var check = $.inArray(sParentValue, dTrackerArray);
while(check > -1)
{
dTrackerArray.splice(check,1);
check = $.inArray(sParentValue, dTrackerArray);
}

You've already stepped through this with a debugger? That's probably all you'd need to do to understand what's happening here. I'd put this in a comment, but I don't have those privileges yet.

Related

Push string to array if the array you want to push from is undefined

I am not a coder, I am messing around with some JavaScript as part of modding a game, so bear with me. This game supports es5/everything Chromium 28 supported.
I had code which pushed a string to an array from a variable, and when the variable was undefined a fixed string was pushed instead:
slotsArray.push({
landing_policy: ai.landing_policy || 'no_restriction'
});
The setup changed such that where ai.landing_policy was set it would contain multiple values, so it become an array. When it wasn't set only a single entry was required.
The same code does not appear to work where an array is in place:
for (var i = 0; i < count; i++) {
slotsArray.push({
landing_policy: ai.landing_policy[i] || 'no_restriction'
});
}
An error is produced because it's trying to check a value from a variable that hasn't been defined. I expected that to cause it to use the fixed value, but apparently that's not what happens, it just fails.
I've changed my approach to the code seen below in full:
if (Array.isArray(ai.landing_policy)) {
for (var i = 0; i < count; i++) {
slotsArray.push({
landing_policy: ai.landing_policy[i]
});
}
}
else {
slotsArray.push({
landing_policy: ai.landing_policy || 'no_restriction'
});
}
This code works, but what I'm looking to understand is whether this was the best solution? The old method felt elegant, while the new one looks a little clumsy.
You can use the ternary operator(? :).
It will return the second value if the first is true, and the third otherwise.
I've used array instanceof Array instead of Array.isArray(array) to support ES5.
var isArray = ai.landing_policy instanceof Array
for (var i = 0; i < (isArray ? count : 1); i++) {
slotsArray.push({
landing_policy: isArray ? ai.landing_policy[i] : ai.landing_policy || 'no_restriction'
});
}
Elegant solution not always converse to the most readable/desirable. I would probably do something like:
const formattedPolicy = ai.landing_policy.map(policy => policy || 'no_restriction');
slotsArray = [...formattedPolicy ];
Course this has to imply that the ai.landing_policy is always an array. If you need to double check first you could also do:
const formattedPollicy = ai.landing_policy.constructor === Array
? ai.landing_policy.map(policy => policy || 'no_restriction');
: [ai.landing_policy]
Looks like an elegant or short imho but your code is way more readable.

How to find the missing next character in the array?

I have an array of characters like this:
['a','b','c','d','f']
['O','Q','R','S']
If we see that, there is one letter is missing from each of the arrays. First one has e missing and the second one has P missing. Care to be taken for the case of the character as well. So, if I have a huge Object which has all the letters in order, and check them for the next ones, and compare?
I am totally confused on what approach to follow! This is what I have got till now:
var chars = ("abcdefghijklmnopqrstuvwxyz"+"abcdefghijklmnopqrstuvwxyz".toUpperCase()).split("");
So this gives me with:
["a","b","c","d","e","f","g","h","i","j","k","l","m",
"n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
Which is awesome. Now my question is, how do I like check for the missing character in the range? Some kind of forward lookup?
I tried something like this:
Find the indexOf starting value in the source array.
Compare it with each of them.
If the comparison failed, return the one from the original array?
I think that a much better way is to check for each element in your array if the next element is the next char:
function checkMissingChar(ar) {
for (var i = 1; i < ar.length; i++) {
if (ar[i].charCodeAt(0) == ar[i-1].charCodeAt(0)+1) {
// console.log('all good');
} else {
return String.fromCharCode(ar[i-1].charCodeAt(0)+1);
}
}
return true;
}
var a = ['a','b','c','d','f']
var b = ['O','Q','R','S']
console.log(checkMissingChar(a));
console.log(checkMissingChar(b));
Not that I start to check the array with the second item because I compare it to the item before (the first in the Array).
Forward Look-Ahead or Negative Look-Ahead: Well, my solution would be some kind of that. So, if you see this, what I would do is, I'll keep track of them using the Character's Code using charCodeAt, instead of the array.
function findMissingLetter(array) {
var ords = array.map(function (v) {
return v.charCodeAt(0);
});
var prevOrd = "p";
for (var i = 0; i < ords.length; i++) {
if (prevOrd == "p") {
prevOrd = ords[i];
continue;
}
if (prevOrd + 1 != ords[i]) {
return String.fromCharCode(ords[i] - 1);
}
prevOrd = ords[i];
}
}
console.log(findMissingLetter(['a','b','c','d','f']));
console.log(findMissingLetter(['O','Q','R','S']));
Since I come from a PHP background, I use some PHP related terms like ordinal, etc. In PHP, you can get the charCode using the ord().
As Dekel's answer is better than mine, I'll try to propose somewhat more better answer:
function findMissingLetter (ar) {
for (var i = 1; i < ar.length; i++) {
if (ar[i].charCodeAt(0) != ar[i-1].charCodeAt(0)+1) {
return String.fromCharCode(ar[i-1].charCodeAt(0)+1);
}
}
return true;
}
var a = ['a','b','c','d','f']
var b = ['O','Q','R','S']
console.log(findMissingLetter(a));
console.log(findMissingLetter(b));
Shorter and Sweet.

JavaScript && JQuery : Iterating

I have managed to get so far but for some reason, it does not match the last number and run the else command I have in the code.
My current code is:
JavaScript Fiddle
If anyone could point me in the right direction it would be very much appreciated as I've spent the last 2 hours trying to figure this problem out and only managed to get this far.
The next and Previous works fine, along with the View more/less. Its the 'View next address' that the code seems to skip the else.
This code here is always skipped, my question is does anyone know why or can point me in the direction of fixing this?
else {
$(".activee").eq(idx).addClass("hidden");
$(".activee").eq(idx).removeClass("activee").prev().addClass("activee");
alert("Sorry, there is no more addresses to show...");
num[idx]--;
}
Thanks in advance!
Change your fiddle to this:
var num = []; // <-- changed to array from object
for (i = 0; i < leng; i++) { // <-- while i < leng
num.push(i);
}
Updated fiddle
for (i = 0; i == leng; i++) {
num.push(0);
}
you're pushing the value 0 to the num array
probably meant to do
for (i = 0; i == leng; i++) {
num.push(howMany[i]);
}
but I just skimmed the code, so am not sure whether the logic is even valid.

JS: Using Length Property to Write If Statement

I'm very new to JS so go easy on me. I've got this array inside a variable, and am trying to find a better way to write that if statement. So if the names inside that variable grow, I won't need to change the if statement as it won't be hardcoded.
var names = ["beth", "barry", "debbie", "peter"]
if (names[0] && names [1] && names [2] && names [3] {
Do something...
}
Something tells me I need to be using the .length property but I can't work out how to properly use it within that statement. Something along the lines of:
if (names[i] * names.length) {
Do something...
}
I know that's wrong. I think need to be finding the index of each and looping through it makign sure it the loop doesn't exceed the amount of values in the array.
Any help is appreciated. Thanks in advance!
Update: Some users have alerted me that my question might not be as clear. I've setup a CodePen here (http://codepen.io/realph/pen/KjCLd?editors=101) that might explain what I'm trying to achieve.
P.S. How do I stop my from repeating 3 times?
You can use every to test whether every element satisfies some condition:
if (names.every(function (name) { return name })) {
// Do Something
}
every will automatically stop testing when the first non-true element is found, which is potentially a large optimization depending on the size of your array.
Traditionally, you would simply iterate over the array and test each element. You can do so with forEach or a simple for loop. You can perform the same early-termination when you find a non-true element by returning false from the forEach callback.
var allTrue = true;
names.forEach(function (name) {
return allTrue = allTrue && name;
});
if (allTrue) {
// Do something...
}
Please give a english description of what you are trying to accomplish. The below answer assumes you simply want to iterate a list of names and do some processing with each.
You want to use a for loop.
var names = ["beth", "barry", "debbie", "peter"]
for (var i=0; i<names.length; i++) {
// access names[i]
}
The best cross-browser solution is to use a traditional for loop.
var names = ["beth", "barry", "debbie", "peter"],
isValid = true,
i;
for (i = 0; i < names.length; i++) {
isValid = isValid && names[i];
}
if (isValid) {
// do something
}
You can try this;
var checkCondition = true;
for(var i = 0; i<names.length; i++){
if(names[i] !== something) {
checkCondition = false;
break;
}
}
if(checkCondition){
//Do what ever you like if the condition holds
}else{
// Do whatever you like if the condition does NOT holds
}
If i understand right you need something like this
var names = ["beth", "barry", "debbie", "peter"];
var notUndefinedNames = names.filter(function(el){return el !== undefined;});
// if all
if (names.length === notUndefinedNames.length) console.log("You're all here. Great! Sit down and let's begin the class.");
// if one or less
else if (notUndefinedNames.length <= 1) console.log("I can't teach just one person. Class is cancelled.");
else console.log("Welcome " + notUndefinedNames.join(', '));

javascript array for loop i+1 returning undefined

array ref.length = 7 (0 - 6), and I want to try to match ref[0]['x'] to ref[1]['x'] I am doing this:
for(var i=0;i<ref.length;i++){
if( ref[i]['x'] != ref[i+1]['x'] && ref[i+1]['x'].length > 0 )
//do something
}
The for loop is iterating all the way to array number 6 then element 6+1 is blank so I get an error on the if statement line saying ref[i+1] is undefined....
is there a better way to do this?
Better:
for (var i=ref.length-2;i>=0;i--)
Javascript will evaluate the condition on each iteration, so it's generally preferable go backwards instead. With this construct "ref.length" is only evaluated once. Another alternative I like which will perform the same:
var i=ref.length-1;
while (i--) {
}
(Normally you'd be i=ref.length-1 in the first example, and i=ref.length in the second, but you're trying to stay one less than the array length).
for (var i=0; i<ref.length-1; i++) { // Note the "-1".
This way when you use the index i+1 you're still in bounds.
for (var i = 0; i < ref.length - 1; i++)
What about:
for(var i=0;i<ref.length-1;i++){
If you just use ref.length-1 won't that solve your problem? I might not fully understand what you're asking.
Here's a simple solution.
Just count the counter again.
if( ref[i]['x'] != ref[++i]['x'] && ref[++i]['x'].length > 0 )

Categories

Resources