Jump to content

Alternative to Foreach


ryan9402

Recommended Posts

So I made a script to print letters on a curve, I already tried looking for an answer on google. Each had different skew values so I broke up the letters into an array and used array combine. I used the foreach function and now it only prints one letter. Example: Input: Hello Output: Helo All help or guidance is appreciated.

 

Thanks,

Ryan

 

Is there a way to fix this? Here is the code:

<?PHP

$place = count($upper_split);

if($debug == "1")
{
	print 'The amount of characters is '.$place.'<br />';
	print_r ($upper_split);
}

if($place == "1")
{
	die("Not enough characters!");
}
elseif($place == "2")
{
	$p2 = array(
	"base1",
	"base2"
	);
}elseif($place == "3")
{
	$p2 = array(
	"base1",
	"base2",
	"1"
	);
}elseif($place == "4")
{
	$p2 = array(
	"-1",
	"base1",
	"base2",
	"1"
	);
}elseif($place == "5")
{
	$p2 = array(
	"-2",
	"-1",
	"base1",
	"base2",
	"1"
	);
}elseif($place == "6")
{
	$p2 = array(
	"0" => "-2",
	"1" => "-1",
	"2" => "base1",
	"3" => "base2",
	"4" => "1",
	"5" => "2"
	);
}elseif($place == "7")
{
	$p2 = array(
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2"
	);
}elseif($place == "8")
{
	$p2 = array(
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3"
	);
}elseif($place == "9")
{
	$p2 = array(
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3"
	);
}elseif($place == "10")
{
	$p2 = array(
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4"
	);
}elseif($place == "11")
{
	$p2 = array(
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4"
	);
}elseif($place == "12")
{
	$p2 = array(
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5"
	);
}elseif($place == "13")
{
	$p2 = array(
	"-6",
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5"
	);
}elseif($place == "14")
{
	$p2 = array(
	"-6",
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6"
	);
}elseif($place == "15")
{
	$p2 = array(
	"-7",
	"-6",
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6"
	);
}elseif($place == "16")
{
	$p2 = array(
	"-7",
	"-6",
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6",
	"7"
	);
}elseif($place == "17")
{
	$p2 = array(
	"-8",
	"-7",
	"-6",
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6",
	"7"
	);
}elseif($place == "18")
{
	$p2 = array(
	"-8",
	"-7",
	"-6",
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6",
	"7",
	"8"
	);
}elseif($place == "19")
{
	$p2 = array(
	"-9",
	"-8",
	"-7",
	"-6",
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6",
	"7",
	"8"
	);
}elseif($place == "20")
{
	$p2 = array(
	"-9",
	"-8",
	"-7",
	"-6",
	"-5",
	"-4",
	"-3",
	"-2",
	"-1",
	"base1",
	"base2",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6",
	"7",
	"8",
	"9"
	);
}

if($debug == "1")
{
	print '<br />DEBUG LINE 302<br />';
	print_r ($p2);
	if(empty($p2))
	{
		print 'No items in array!';
		print '<h3>Combined Array:</h3> <br />';
		$carr = array_combine($upper_split, $p2);
		print_r($carr);
	}
}

foreach (array_combine($upper_split, $p2) as $char => $pos_1)
{
	if($pos_1 == "-9")
	{
		$x = "54.2832";
		$y = "127.1807";
		$skew = "0.0973 -0.4904 0.9809 0.1945";
	}
	elseif($pos_1 == "-8")
	{
		$x = "57.3301";
		$y = "113.0444";
		$skew = "0.1865 -0.4639 0.9279 0.3729";
	}
	elseif($pos_1 == "-7")
	{
		$x = "62.9707";
		$y = "99.6519";
		$skew = "0.265 -0.424 0.848 0.53";
	}
	elseif($pos_1 == "-6")
	{
		$x = "70.9082";
		$y = "87.3872";
		$skew = "0.3305 -0.3752 0.7504 0.6609";
	}
	elseif($pos_1 == "-5")
	{
		$x = "80.7759";
		$y = "76.5127";
		$skew = "0.3831 -0.3214 0.6427 0.7661";
	}
	elseif($pos_1 == "-4")
	{
		$x = "92.2236";
		$y = "67.1782";
		$skew = "0.4242 -0.2648 0.5295 0.8483";
	}
	elseif($pos_1 == "-3")
	{
		$x = "104.8765";
		$y = "59.5078";
		$skew = "0.4552 -0.207 0.4139 0.9103";
	}
	elseif($pos_1 == "-2")
	{
		$x = "118.438";
		$y = "53.541";
		$skew = "0.4774 -0.1488 0.2976 0.9547";
	}
	elseif($pos_1 == "-1")
	{
		$x = "132.6865";
		$y = "49.2866";
		$skew = "0.4917 -0.0905 0.1811 0.9835";
	}
	elseif($pos_1 == "base1")
	{
		$x = "147.3794";
		$y = "46.7573";
		$skew = "0.4989 -0.0329 0.0657 0.9978";
	}
	elseif($pos_1 == "base2")
	{
		$x = "162.2515";
		$y = "45.9419";
		$skew = "0.4994 0.0237 -0.0475 0.9989";
	}
	elseif($pos_1 == "1")
	{
		$x = "177.1421";
		$y = "46.814";
		$skew = "0.4933 0.0813 -0.1626 0.9867";
	}
	elseif($pos_1 == "2")
	{
		$x = "191.7734";
		$y = "49.3921";
		$skew = "0.4802 0.1394 -0.2788 0.9604";
	}
	elseif($pos_1 == "3")
	{
		$x = "205.999";
		$y = "53.6982";
		$skew = "0.4592 0.1978 -0.3955 0.9185";
	}
	elseif($pos_1 == "4")
	{
		$x = "219.5259";
		$y = "59.7124";
		$skew = "0.4297 0.2557 -0.5113 0.8594";
	}
	elseif($pos_1 == "5")
	{
		$x = "232.1196";
		$y = "67.4126";
		$skew = "0.3903 0.3125 -0.6249 0.7807";
	}
	elseif($pos_1 == "6")
	{
		$x = "243.4849";
		$y = "76.7485";
		$skew = "0.3397 0.3669 -0.7338 0.6793";
	}
	elseif($pos_1 == "7")
	{
		$x = "253.2744";
		$y = "87.6104";
		$skew = "0.2763 0.4167 -0.8334 0.5526";
	}
	elseif($pos_1 == "8")
	{
		$x = "261.1313";
		$y = "99.8262";
		$skew = "0.1999 0.4583 -0.9166 0.3998";
	}
	elseif($pos_1 == "9")
	{
		$x = "266.7222";
		$y = "113.1919";
		$skew = "0.112 0.4873 -0.9746 0.2241";
	}
	else{
		$error = "Error: The position was not found for place code: [".$pos_1."] [Function 'find_postion' on line 39 functions.php]";
	}
	
	$font = "'Arial Black'";
	$before ='<text transform="matrix(';
	$after = ')" stroke="#000000" stroke-width="0.5616" font-family="'.$font.'" font-size="36">'.strtoupper($char).'</text>
';
	$complete = ''.$before.''.$skew.' '.$x.' '.$y.' '.$after.'';
	
	file_put_contents('svg/temp/'.md5($_SERVER['REMOTE_ADDR']).'.part3.txt', ''.$complete.'', FILE_APPEND | LOCK_EX);
}

?>
Link to comment
https://forums.phpfreaks.com/topic/284201-alternative-to-foreach/
Share on other sites

What is the output of print_r for $upper_split and $p2 It is probably array_combine that is the issue not foreach.

 

However to answer your quest the alternative to foreach would be while loop with each() (see Example #2) or a for loop

This is the output of print_r is Array ( [0] => -2 [1] => -1 [2] => base1 [3] => base2 [4] => 1 ) Array ( [H] => -2 [e] => -1 [l] => base2 [o] => 1 ) 

So it looks like the issue is array combine..

Off topic: If you find yourself writing what appears to be repetitive code - such as in your series of ifelse() statements to define $p2 - stop - you're doing it wrong. You can replace all of that code with the code below. I didn't test it thoroughly, but I think it's correct.

    $p2List = array(
        "-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", "base1",
        "base2", "1", "2", "3", "4", "5", "6", "7", "8", "9"
    );
    $p2ListCount = count($p2List);
    
    if($placeCount<2 || $placeCount>$p2ListCount)
    {
        die("Invalid number of characters: {$placeCount}!");
    }

    $startIndex = ceil(($p2ListCount-$placeCount) / 2);
    $p2 = array_slice($p2List, $startIndex, $placeCount);

No. The issue is your design.   An associative array can not have 2 items with the same key. Latter overwrites former.

 

$arr = array('keyone'=>1,'keyone'=>2);

 

get keyone? which keyone? nope.   no such which there's only one keyone and it  === 2 .....    $arr['keyone'] === 2

Oh thats why you are using the letters are keys. The second L letter is over writing the first L letter in the word hello. You should set the positions as the key and the letters as the value.

 

Basically swap the parameters around for when you call array_combine

$carr = array_combine($p2, $upper_split);

Then the foreach construct becomes (swap $pos_1 and $char around)

foreach (array_combine($upper_split, $p2) as $pos_1 => $char)

 

Oh thats why you are using the letters are keys. The second L letter is over writing the first L letter in the word hello. You should set the positions as the key and the letters as the value.

 

Basically swap the parameters around for when you call array_combine

$carr = array_combine($p2, $upper_split);

Then the foreach construct becomes (swap $pos_1 and $char around)

foreach (array_combine($upper_split, $p2) as $pos_1 => $char)

Thanks, this worked!

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.