Javascript Objects in array selection - javascript

Hello stackoverflowians~!
It is I, a lonesome programmer who has encountered a problem during my trails.
You see the problem is with this piece of code.
for(var a = 0; a < bullets.length; a++) {
for(var b = 0; b < pigs.length; b++) {
if(bullets[a].y < 300) {
if(bullets[a].x > pigs[b].x && bullets[a].x < pigs[b].x + pigImage.width &&
bullets[a].y > pigs[b].y && bullets[a].y < pigs[b].y + pigImage.height) {
pigExplode(pigs[b].x);
bullets.pop(a);
pigs.pop(b);
player.kills++;
}
}
}
}
The problem is as following.
I have 2 arrays with objects inside of them;
one array Bullets holding all bullet objects
and one array Pigs which hold all the pigs (Targets to shoot in my game)
(However, I do not encourage shooting pigs in any way)
Now what I'm trying to do is see if one of the bullets in the array hits one of the pigs in the array, i've added the pigs and bullets into the arrays like this:
bullets.push(new Bullet());
pigs.push(new Pig());
Where shit goes south is when I try to remove a certain object in this array, lets say I have 5 pigs.
that would be 0, 1, 2, 3, 4.
If I were to shoot pig 2. 4 will die.
If I were to shoot pig 1. 4 will die.
If I were to shoot pig 4. 4 will die.
So no matter who I shoot it will always remove the last pig.
the error I get with this problem is this:
Uncaught TypeError: Cannot read property 'y' of undefined
The line it indicates is this:
if(bullets[a].y < 300) {
this is in the double for loop where I check for any bullets hitting the pig.
the error however only pops up when I hit a pig that is not the last in the array.
Does anyone have any idea what's going on with my code?
I've been dealing with this for several days now and I have no idea what I'm doing wrong.
Thanks in advance!

There are two problems with the code:
You are using pop to remove items from the arrays, that will always remove the last item. That's why it's always killing the last pig.
You are continuing the inner loop after a hit, so you will be checking hits for a bullet that's not in the array any more. If you were checking the last bullet, the variable a is now pointing beyond the last item in the array.
Use splice to remove items in an array, loop backwards through the bullets so that you can remove one without messing up the loop, and end the inner loop after a hit:
for (var a = bullets.length - 1; a >= 0; a--) {
for (var b = 0; b < pigs.length; b++) {
if (bullets[a].y < 300) {
if (bullets[a].x > pigs[b].x && bullets[a].x < pigs[b].x + pigImage.width &&
bullets[a].y > pigs[b].y && bullets[a].y < pigs[b].y + pigImage.height) {
pigExplode(pigs[b].x);
bullets.splice(a, 1);
pigs.splice(b, 1);
player.kills++;
break; // end the inner loop
}
}
}
}

This will remore the pig from your pigs array if it's hit
if(bullets[a].x > pigs[b].x && a bunch of other stuff) {
pigExplode(pigs[b].x);
bullets.splice(a,1);//remove bullit at a
pigs.splice(b,1);//remove pig at b
player.kills++;//smell bacon, jummy
//always forget this both bullits and pigs are one shorter
// if you dont decrease the counters you'll skip one pig and bullit
a--;
b--;
}
.pop always removes the last item of the array.

Related

leetcode.com - Remove Element - why doesn't i++ work?

I am working on an algorithm from leetcode.
here is the description:
Given an array and a value, remove all instances of that value in
place and return the new length. Do not allocate extra space for
another array, you must do this in place with constant memory. The
order of elements can be changed. It doesn't matter what you leave
beyond the new length. Example: Given input array nums = [3,2,2,3],
val = 3 Your function should return length = 2, with the first two
elements of nums being 2.
My question is based on the following code:
var removeElement = function(nums, val) {
var count = 0;
for(i=0; i<nums.length; i++){
if(nums[i] == val) {
nums.splice(i,1);
i--;
}
}
};
My question is, why does decrementing with i-- work but incrementing with i++ does not work?
A situation in which my answer is not accepted is when the input array is [3, 3], and the value is 3.
Splice removes the element at i from the array, so you need to stay at the current position, if you want to go on iterating normally. As theres an i++ in the for loop, it would normally go one position forward. So you need to go one step backward before to stay at the same position.
nums=[3,2,2,3]
val=3;
//first iteration
i=0
current=3//===val
nums.splice(0,1);//nums=[2,2,3]
i--;//i=-1
//next iteration
i++;//i=0
current=2;
//next iteration
i++;//i=1
current=2;
//next iteration
i++;//i=2
current=3;
nums.splice(2,1);//nums=[2,2]
i--;//i=1
//next iteration
i++;//i=2 === nums.length => break
In the case [3,2,2,3] it does not matter if you use i++ instead of i-- as it will jump over indexes 1 and 2 wich are not relevant. So this buggy code works by accident...

Google Apps Script .add Item recursively?

So after taking a look at this URL: Adding Items
The basis is that I can't really add items recursively to a new menu. I seem to have made some progress with the following code:
function onOpen(e) {
var menu = SpreadsheetApp.getUi().createAddonMenu();
var vendorsheet = SpreadsheetApp.openById('1Bt4s9aOfjkCyZRvHZMjMdntgID2VYF7Qzmjc7Z7YP1E')
for(var i = 2; i < 5; i++){
var j = 4;
menu.addItem(String(vendorsheet.getRange('A'+ String(i)).getValue()),'Test')
if(i = j){
menu.addItem(String(vendorsheet.getRange('A'+ String(i)).getValue()),'Test')
} else {
menu.addItem(String(vendorsheet.getRange('A'+ String(i)).getValue()),'Test')
}
}
menu.addToUi();
}
It only adds two items. It seems as though the menu.addItem function only adds one item per one call of it. You can't use a for loop to call it recursively. If someone could help me add "n" items recursively for any n that would be preferable. Thank you.
First of all, your code is not recursive. As corn3lius rightly says, this code is iterative. I'm pretty sure I know why your code is malfunctioning though.
Your if statement is actually an assignment statement. You want if (i == j) not if (i = j)
Edit:
To clarify, why you're only getting two entries:
1) i = 2 // You assign 2 to i
2) addItem(...) // Entry one
3) if (i = j) // This is actually considered a trueish statement and gives you your boolean true and sets i = 4
4) addItem(...) // Second entry
5) i++ // i is now equal to 5
6) if (i < 5) // False, 5 == 5 not 5 < 5, exit the loop.

Returning duplicates in multidimensional Javascript array

I have searched high and low, not only on StackOverflow, but many other places elsewhere on the web. I've tried what seems like everything, but something is fundamentally flawed with my logic. I apologize for introducing another "Duplicates in Array" question, but I am stuck and nothing seems to be working as expected.
Anyway, I have a multi-dimensional JavaScript array, only 2 levels deep.
var array = [[Part #, Description, Qty:],
[Part #, Description, Qty:],
[Part #, Description, Qty:]]; //etc
What I need to do is create a function that searches array and returns any duplicate "Part #" lines. When they are returned, I would like to have the entire inner array returned, complete with description and qty.
The trick with this is that the Part #'s that would qualify as 'duplicate' would end differently (specifically the last 4 characters), so using String.prototype.substr makes sense (to me).
I know there are duplicates in the array in the way that I am looking for, so I know that if I had the solution, it would return those Part #'s.
Here is what I have tried so far that gets me the closest to a solution:
function findDuplicateResults(arr) {
var result = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i][0].substr(0,5) === arr[++i][0].substr(0,5)) {
result.push(arr[i]);
}
}
return console.log(result);
}
My thinking is that if the element in the array(with substr(0,5) is equal to the next one in line, push that to the result array. I would need the other duplicate in there too. The point of the code is to show only dupes with substr(0,5).
I have tried using Higher Order Functions such as map, forEach, reduce, and filter (filter being the one that boggles my mind as to why it doesn't do what I want), but I have only been able to return [] or the entire array that way. The logic that I use for said Higher Order Functions remains the same (which is probably the problem here).
I am expecting that my if condition is where the most of the problem is. Any pointers or solutions are greatly appreciated.
There is a mistake in your code. When you use ++i, you are changing the value of i, so it is going to skip one item in the next iteration.
Regarding the logic, you are only comparing one item to the next item, when you should really be comparing each item to all items:
function findDuplicateResults(arr) {
var result = [];
for (var i = 0; i <= arr.length - 1; i++) {
for (var k = 0; k <= arr.length - 1; k++) {
if (i !== k && arr[i][0].substr(0,5) === arr[k][0].substr(0,5)) {
result.push(arr[i]);
}
}
}
return result;
}
Although, the 'substr' could be dropped, and 'for' loop could be replaced by a higher order function:
function findDuplicateResults(arr) {
return arr.filter(function(item1){
return arr.filter(function(item2){
return item1[0] === item2[0];
}).length > 1;
});
}

How to create and display result one at a time in an infinite loop in javascript?

I'm fairly new to HTML and Javascript. I want to know how to create an infinite loop from, let's say, myArray, list, or whatever and then display result one at a time. Can you please give me an example, hints, or anything with detailed explanation of how it works? I just want to understand on how things work. Thanks!
A very basic loop is a while loop:
while (condition) {
//code block to be executed
}
Typically you would use it like so:
var i = 0;
while (i < 10) {
//code block to be executed
i++;
//This block of code will continue until i >= 10
//adding 1 to the value of I each iteration
}
Easiest way to do a endless loop:
while (true) {
code block to be executed
}
//true will always be true so this will continue until it
//hits a return; statement, the end of time, or the software
//or hardware gives up
A common mistake that end up in an endless loop:
var i = 0;
while (i < 10) {
code block to be executed
//In this example i is never being increased so
//i will always be less than 10
}
A very practical way to do a while loop correctly:
var array = ['a','b','c'];
var i = 0;
while (i < array.length) {
alert(array[i]);
i++;
}
//This will alert a, alert b, then alert c
Another way to do the above is using a for loop:
var array = ['a','b','c'];
for (var i = 0; i < array.length; i++) {
alert(array[i];
}
//for loops are a good practice because you are less
//likely to leave out steps like defining the iterator,
//or increasing the iterator
OP
I'm trying to create something using HTML/Javascript that everytime I press a button called next item (I created one using <form></form>) it would display an item, or an image. The trick is I don't know how to keep displaying the item after the last position. After the last position it should go back to the first position. For example, for the array that you provide in your example you have [a, b, c], after I displayed c and press the button again I want to display a again and so forth. Can you give me hints or any other valuable info on how to do this?
Answer
JSFiddle Example:
http://jsfiddle.net/d2809p6z/
HTML
<button id="button">click me</div>
JS
var array = ['a','b','c'];
var index = 0;
document.getElementById('button').onclick=function(){
if (index >= array.length) {
index = 0;
}
alert(array[index]);
index++;
};

Javascript stuck at "for" loop

i am newbie learner and i am learning basic javaScript from codecademy.I stuck at "Search Text for Your Name" tutorial 5/7.
here is my question:
your loop should stop when it hits the value of the first iterator (say, i)
plus the length of your myName variable.
here is some informations from to tutorial:
Your second "for" loop
Okay! Last loopy step: add another for loop, this time inside the body of your if statement (between the if's {}s).
This loop will make sure each character of your name gets pushed to the final array. The if statement says: "If we find the first letter of the name, start the second for loop!" This loop says: "I'm going to add characters to the array until I hit the length of the user's name." So if your name is 11 letters long, your loop should add 11 characters to hits if it ever sees the first letter of myName in text.
For your second for loop, keep the following in mind:
First, you'll want to set your second loop's iterator to start at the first one, so it picks up where that one left off. If your first loop starts with
> for(var i = 0; // rest of loop setup
your second should be something like
> for(var j = i; // rest of loop setup Second
think hard about when your loop should stop.
Finally, in the body of your loop, have your program use the .push() method of hits. Just like strings and arrays have a .length method, arrays have a .push() method that adds the thing between parentheses to the end of the array. For example,
newArray = [];
newArray.push('hello');
newArray[0]; // equals 'hello'
and here is my code:
multistr:true
var text = "Hey, how are you \
doing? My name is Emily.";
var myName = "Emily";
var hits = [];
for (var i = 0; i > text.length; i++)
{
if (text[i] === 'E')
{
for(var j = i; j > text.length; j++){
};
};
};
ps: i don't want to pass this tutorial without understand it. please help me. teach me.
for (var i = 0; i > text.length; i++) should be
for (var i = 0; i < text.length; i++)
otherwise it won't ever meet the criteria to even start the loop.
Welcome on board! You confused > with <. Your loops won't run because for the first check when i = 0 it certainly does not hold that 0 > text.length, because text.length is at least 0 (there are no strings shorter than the empty string).
You should make a habit of manually going through your loops for the first two steps and then check what happens just before the loop ends.
Here is what I got for my code:
for ( i = 0; i < text.length; i++)
{
if ( text[i] === "E")
{
for( var j = i; j < (myName.length + i ); j++)
{
hits.push(text[j]);
}
}
};
It looks like you were missing the " + i " part in your second for loop. That seems to make sure that the first loop will be included. I tried it without the "+ i" and it does not work.
I tried continuing directly from the second for loop using a "+ j" and that only crashes the browser.

Categories