PHP Undefined offset: -1, how can I skip the negative index? - arrays

I already have a program in java which works fine. I tried writing the same one in php and got to some errors.
For example, in this code
for ($i=0; $i<64; $i++) {
$r=$i/8;
$c=$i%8;
$temp=1;
for ($j=-1; $j<=1; $j+=2) {
for ($k=-1; $k<=1; $k+=2) {
while(" " == $chessBoard[$r+$temp*$j][$c+$temp*$k])
{
//some other code here
}
}
}
}
$chessBoard is a two dimensional array
$chessBoard= array
(
array("r","k","b","q","a","b","k","r"),
array("p","p","p","p","p","p","p","p"),
array("0","0","0","0","0","0","0","0"),
array("0","0","0","0","0","0","0","0"),
array("0","0","0","0","0","0","0","0"),
array("0","0","0","0","0","0","0","0"),
array("P","P","P","P","P","P","P","P"),
array("R","K","B","Q","A","B","K","R")
);
I know that the error happens when I'm trying to access $chessBoard[$r+$temp*$j][$c+$temp*$k] when for example $r is 0 and $j is -1, then I get 0+1*-1 which is -1, but I don't know how to get rid of this problem and still have the program to work properly. It's still not clear to me why I didn't have the same problem in java.

Before the code
while(" " == $chessBoard[$r+$temp*$j][$c+$temp*$k])
{
//some other code here
}
put in:
if($r+$temp*$j < 0 || $c+$temp*$k) continue;
This will go to the next iteration of the for-loop and will not run into any indexoutofboundsexception

Related

Counting how many numbers greater than 5 in a given array

I am having an error saying that prototype not terminated at filename.txt line number 113 where as line number 113 belongs to a different program which is running successfully.
sub howmany(
my #H = #_;
my $m = 0;
foreach $x (#H) {
if ( $x > 5 ) {
$m +=1;
}
else {
$m +=0;
}
}
print "Number of elements greater than 5 is equal to: $m \n";
}
howmany(1,6,9);
The sub keyword should be followed by { } not ( ) (if you define a simple function), that's why the error
prototype not terminated
After this, always start with : use strict; use warnings;
Put this and debug your script, there's more errors.
Last but not least, indent your code properly, using an editor with syntax highlighting, you will save many time debugging
The error is due to parenthesis.
Never do $m += 0; As you actually load processor for nothing. Of course it's not gonna be visible on such a small function, but...
sub howmany {
my $m = 0;
foreach (#_) {
$m++ if ($_ > 5);
}
print "Number of elements greater than 5 is equal to: $m \n";
}
howmany(1,6,9);

Error while using removeChild() and accessing members of array

I am stuck doing this even though I know it's very simple. Yet, I am getting errors.
What I have:
I have 3 arrays.
1st Array contains objects of UpgradeButton class.
2nd Array contains objects of BuyButtonclass.
3rd Array named newCostlyShops contains Numbers.
BuyButton class and UpgradeButton class, both have a shopCode member which is a number; the number which I'm trying to equate.
What I'm trying to do:
My goal is to first look for BuyButton and UpgradeButton objects in the respective arrays which have shopCodes same as those in newCostlyShops.
After that, I removeChild() that object and splice it out from the array.
My Code:
Array 3:
var newCostlyShops:Array = new Array();
newCostlyShops = Object(root).WorkScreen_mc.returnCostlyShops();
trace(newCostlyShops); // this is tracing out the exact shopCodes I want and is working fine.
Deletion and Splicing codes:
for (looper = 0; looper < upgradeButtonsArray.length; looper++) {
for (var secondLooper: int = 0; secondLooper < newCostlyShops.length; secondLooper++) {
if (upgradeButtonsArray[looper].shopCode == newCostlyShops[secondLooper]) {
trace(looper);
trace(upgradeButtonsArray[looper]);
removeChild(upgradeButtonsArray[looper]);
upgradeButtonsArray.splice(looper, 1);
}
}
}
for (looper = 0; looper < buyButtonsArray.length; looper++) {
for (secondLooper = 0; secondLooper < newCostlyShops.length; secondLooper++) {
if (buyButtonsArray[looper].shopCode == newCostlyShops[secondLooper]) {
trace(looper);
trace(buyButtonsArray[looper]);
removeChild(buyButtonsArray[looper]);
buyButtonsArray.splice(looper, 1);
}
}
}
What's wrong with this Code:
I keep getting error
TypeError: Error #1010: A term is undefined and has no properties.
This error comes only after the 1st time this code is run and not the first time it is run. When I remove the removeChild and splice , this traces out objects that are not null, ever. Even after this whole function is called 100 times, the error is not shown. Only when I removeChild and use splice this occurs.
Is there something wrong with what I'm doing? How to avoid this error? This is throwing the whole program haywire. If there is any other alternative to this method, I'm open to take those methods as well as long as I don't get errors and my goal is reached.
It might sounds funny, but.... try to decrement looper after splicing.
trace(looper);
trace(upgradeButtonsArray[looper]);
removeChild(upgradeButtonsArray[looper]);
upgradeButtonsArray.splice(looper, 1);
looper--;
I think after splicing the array all item's are being shifted and you're skipping next one.
Also, you should get some more information with this error, like which class/line is throwing it. Maybe you need to enable "permit debugging" or something?
Bonus suggestion:
For newCostlyShops use Dictionary instead of Array so you won't have to nest for inside for...

Arrays and if statements. How to check if value is in array? *javascript*

So I have a program that sends emails. The user has a list of emails that cannot be sent to. These are in arrays and I need to use a if statement to determine if what the user entered in is in the array of emails. I tried the in function which didnt work but Im probably just using it wrong. I tried for loops and if statements inside. But that didnt work either. Here is a snapshot of the code Im using to help you get the idea of what im trying to do.
function test2(){
var safe = [1]
safe[1] = "lol"
safe[2] = "yay"
var entry = "lol"
Logger.log("entry: " + entry)
for(i = 0; i < safe.length; i++){
if(entry == safe[i]){
Logger.log("positive")
}else{
Logger.log("negative")
}
}
}
Here is what I tried with the in function to show you if I did it wrong
function test(){
var safe = [1]
safe[1] = "lol"
safe[2] = "yay"
var entry = "losl"
Logger.log("entry: " + entry)
if(entry in safe){
Logger.log("came positive")
}else{
Logger.log("came negative")
}
Logger.log(safe)
}
array.indexOf(element) > -1 usually does the trick for these situations!
To expand upon this:
if (array.indexOf(emailToSendTo) < 0) {
// send
}
Alternatively, check this cool thing out:
emailsToSend = emailsToSend.filter(function(x) {
// basically, this returns "yes" if it's not found in that other array.
return arrayOfBadEmails.indexOf(x) < 0;
})
What this does is it filters the list of emailsToSend, making sure that it's not a bad email. There's probably an even more elegant solution, but this is neat.

Perl Modification of non creatable array value attempted, subscript -1

I have a Perl-Script, which executes a recursive function. Within it compares two elements of a 2dimensional Array:
I call the routine with a 2D-Array "#data" and "0" as a starting value. First I load the parameters into a separate 2D-Array "#test"
Then I want to see, if the array contains only one Element --> Compare if the last Element == the first. And this is where the Error occurs: Modification of non creatable array value attempted, subscript -1.
You tried to make an array value spring into existence, and the subscript was probably negative, even counting from end of the array backwards.
This didn't help me much...I'm pretty sure it has to do with the if-clause "$counter-1". But I don't know what, hope you guys can help me!
routine(#data,0);
sub routine {
my #test #(2d-Array)
my $counter = $_[-1]
for(my $c=0; $_[$c] ne $_[-1]; $c++){
for (my $j=0; $j<13;$j++){ #Each element has 13 other elements
$test[$c][$j] = $_[$c][$j];
}
}
if ($test[$counter-1][1] eq $test[-1][1]{
$puffertime = $test[$counter][4];
}
else{
for (my $l=0; $l<=$counter;$l++){
$puffertime+= $test[$l][4]
}
}
}
#
#
#
if ($puffertime <90){
if($test[$counter][8]==0){
$counter++;
routine(#test,$counter);
}
else{ return (print"false");}
}
else{return (print "true");}
Weird thing is that I tried it out this morning, and it worked. After a short time of running he again came up with this error message. Might be that I didn't catch up a error constellation, which could happen by the dynamic database-entries.
Your routine() function would be easier to read if it starts off like this:
sub routine {
my #data = #_;
my $counter = pop(#data);
my #test;
for(my $c=0; $c <= $#data; $c++){
for (my $j=0; $j<13;$j++){ #Each element has 13 other elements
$test[$c][$j] = $data[$c][$j];
}
}
You can check to see if #data only has one element by doing scalar(#data) == 1 or $#data == 0. From your code snippet, I do not see why you need to copy the data to passed to routine() to #test. Seems superfluous. You can just as well skip all this copying if you are not going to modify any of the data passed to your routine.
Your next code might look like this:
if ($#test == 0) {
$puffertime = $test[0][4];
} else {
for (my $l=0; $l <= $counter; $l++) {
$puffertime += $test[$l][4];
}
}
But if your global variable $puffertime was initialized to zero then you can replace this code with:
for (my $l=0; $l <= $counter; $l++) {
$puffertime += $test[$l][4];
}

Comparing two associative arrays

I started learning Perl last week.
I have an associative array from a file containing 'tokens' - Just a bunch of numbers.
I have another associative array from an SQL Database containing 'tokens'.
I'm wanting to see if any tokens in the file are NOT in the database. However anything I do doesn't seem to work and I've come to the conclusion that I'm just confusing myself.
I'm not sure I fully understand associative arrays yet but this is a snippet of my code for the file hash:
while($row = <FILE>){
if($row =~ /^000\E/){
#tmp=split(/\s+/,$row);
if($tmp[1] ne "Unassigned"){
$tokenfile{$tmp[0]} = $tmp[1] . " " . $tmp[2];
}
}
}
$tmp[1] + $tmp[2] are the first and second names. I compare names later on to see if they equal each other. However I want to compare $tmp[0] - The token. This is the SQL hash:
while(#rows = $sth->fetchrow_array){
($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwnam("\L$rows[1]\E");
$gcos =~ s/,.*//;
if(!defined($gcos)){
$missing++;
$tokendb{$rows[0]} = $rows[1];
}
else{
$tokendb{$rows[0]} = $gcos;
}
}
$rows[0] is the token.
I assumed I would use two foreach loops such as this:
foreach $token (keys(%tokendb)) {
foreach $token2(keys(%tokenfile)){
if($token ne $token2){
print "$token2 NOT IN DATABASE\n";
}
}
}
But that gives me the result of a lot of values that are still in the database.
I'd love some hints as to why this isn't working. Very frustrating as I know it's something so simple but my brain isn't working so well today (Even though it's my 21st Birthday :|).
foreach $token (keys(%tokenfile)) {
if (! exists $tokendb{$token}) {
print "$token NOT IN DATABASE\n";
}
}
Your nested loop failed because even if a key exists, it doesn't match all the other keys. To do it with a nested loop, it should be:
foreach $token (keys(%tokenfile)) {
$found = 0;
foreach $token2 (keys(%tokendb)) {
if ($token eq $token2) {
$found = 1;
last;
}
}
if (!found) {
print "$token NOT IN DATABASE\n";
}
}
Of course, there's no reason to write it this way, this is just to help you understand how your logic failed.
If you're iterating over a hash and testing every key individually to see whether one of them is a target value, then you're not taking advantage of the power of hashes: Lookups. Try something like
foreach $token (keys(%tokenfile)) {
unless (exists $tokendb{$token}) {
print "$token NOT IN DATABASE\n";
}
}
instead.

Resources