foreach two arrays when one is twice bigger than second - php

Ok so I have two arrays, and the second one is allways twice larger than first one:
$items1 = array('1', '2', '3');
$items2 = array('a', 'b', 'c', 'd', 'e', 'f');
I know that i can foreach two arrays with same items count like this:
foreach ($items1 as $key => $item1)
{
echo $item1 . $items2[$key] . ', ';
}
This will give result like this: 1a, 2b, 3c....
But how to foreach thos two arrays to get result like this:
1ab, 2cd, 3ef?
aka echo first item from $items1 array, an then two from $items2.

foreach (array_combine($items1, array_chunk($items2, 2)) as $key => $value) {
echo $key.implode($value)."\n";
}

You could write:
foreach ($items1 as $i => $item1)
{
echo $item1 . $items2[$i * 2] . $items2[$i * 2 + 1] . ', ';
}

Related

Check if each values are in different arrays

I need to check if element 'a' is present twice, 'b' is present twice and 'c' is present once in a group of arrays. Each element should be in five different arrays.
That is like, 'a' in array1, another 'a' in array2, 'b' in array3, another 'b' in array4 and 'c' in array5. there should be atleast five or more arrays and each element should be in different arrays using php. Now my code is
$arr = array(
$branch1 = array('a', 'b'),
$branch2 = array('b','c'),
$branch3 = array('a', 'c'),
$branch4 = array('c', 'a'),
$branch5 = array('b', 'a'),
$branch6 = array('b', 'c', 'a')
);//This may have any number of branches and any kind of combinations of a, b and c(but each element only once in each array).
$reqd_branch_count = 5;//required branch count
As I am new to php, now I have written a very long code, but it fails when trying new combinations.Please help me if someone knows.
From asker's comment:
The condition is a user has some ranks in his/her downline which are
in branches. for example rank1, rank2 and rank3,.... Those rank counts
are shown in that array. If that user need to get rank8 he/she should
have one rank 7, two rank 5 or 7s, and two rank4s, that should be
1+2+2=5 branches, that is each rank should be in different branches.
Hope you understood the question
if i understood correctly
merge all arrays, count amount of all items in all arrays and test you want
$arr = array_merge($branch1,$branch2,$branch3,$branch4,$branch5,$branch6);
$count = array_count_values($arr);
echo $count[7]; // 4
echo $count[4]; // 2
so, yuo can make condition
if (($count[7] == 1) or ($count[7] == 2) or ($count[5] == 2) or ($count[4] == 2))
{ any stuff for true}
UPDATE
$arr = array(
$branch1=array('3'),
$branch2=array('4'),
$branch3=array('3','5','7'),
$branch4=array('3','4','7'),
$branch5=array('7'),
$branch6=array('4','7'));
// find rank per branch
$ranks = array_map('max', $arr);
// make array rank => amount
$count = array_replace(array_fill(0,7,0), array_count_values($ranks));
if (($count[7] >= 1) and (($count[7] + $count[5]) >= 2) and (($count[7] + $count[5] + $count[4]) >= 5)) {
echo "Satisfy ";
}
Because it is another question, this is another answer
$arr = array(
$branch1 = array('a'),
$branch2 = array('b','c'),
$branch3 = array('a', 'c'),
$branch4 = array('c', 'a'),
$branch5 = array('a'),
$branch6 = array( 'c', 'a')
);
$names = array('a', 'b', 'c'); // for convenience only
var_dump(goNext($arr, $names)); // watch result
function goNext($arr, $names) {
// for each name make array with list of brances where it is
$in = array(array(), array(), array());
foreach($arr as $k1 => $branch)
foreach($names as $k2 => $letter)
if(in_array($letter, $branch)) $in[$k2][] = $k1;
foreach ($in[0] as $i1) // 1st a
foreach (array_diff($in[0], array($i1)) as $i2) // 2nd a
foreach (array_diff($in[1], array($i1,$i2)) as $i3) // 1st b
foreach (array_diff($in[1], array($i1,$i2,$i3)) as $i4) // 2nd b
foreach(array_diff($in[2], array($i1,$i2,$i3,$i4)) as $i5) {
// if here we find combination we need
// next line only for debug
// it shows set of branches that give true
// a a b b c
echo $i1 . " " . $i2 . " " . $i3 . " " . $i4 . " " . $i5;
return(true);
}
return(false); // combination has not found
}

Display data in a html table based on some restriction

$abc=array(1,2,3,4,5,6,7,8);
$xyz=array(a,b,c,d,e,f);
I want to retrieve data from above two arrays in a desired format (Actually those arrays are generated from database tables). The data will be displayed in html TABLE. I have used PHP MYSQL. The values may not be in a sequence as of example been displayed, but there is two distinct arrays. To make it more clear I want to say that the odd columns (starting from first column) will display the values of array abc and even will display the values of array xyz.
Please help me out. Thanks in advance.
This is a really interesting question. I think I found a solution.
function table (array $array1, array $array2, $splitIndex)
{
$rows = array ();
$currentRow = 0;
// Make sure $array1 is the bigger of them
if (count ($array2) > count ($array1))
{
$arrayTemp = $array2;
$array2 = $array1;
$array1 = $arrayTemp;
}
// Loop over each element of the array
foreach ($array1 as $index => $arrayValue)
{
$rows [$currentRow] [] = $arrayValue;
if (isset ($array2 [$index]))
$rows [$currentRow] [] = $array2 [$index];
else
$rows [$currentRow] [] = '';
$currentRow = ($currentRow == $splitIndex ? 0 : $currentRow + 1);
}
$output = '<table>';
// Loop over the rows
foreach ($rows as $row)
{
$subOutput = '<tr>';
// Loop over the columns in the rows
foreach ($row as $element)
$subOutput .='<td>'. $element .'</td>';
$output .= $subOutput .'</tr>';
}
// Return the output altogether.
return $output .'</table>';
}
Now you can use:
echo table ([ 'i', 'b', 'a', 'e', 'b' ], ['1', '2', '3'], 2);
The 2 indicates that it will split on every two rows, like it was 3 in your example.

Why is this php array not returning an error?

<?php
$letters = array( 'A', 'B', 'C' );
$numbers = array( 1, 2, 3 );
$matrix = array( 'Letter' => $letters, 'Number' => $numbers );
echo "<p>Start : {$matrix['Letter'][0]}</p>";
foreach($matrix as $array => $list)
{
echo'<ul>';
foreach($list as $key => $value)
{
echo "<li>$array [$key] = $value";
}
echo '</ul>';
}
?>
I need help understanding this code, essentially I am confused how line #13 is working.
What I see:
'$value' = non-key values of '$list'
'$list' = non-key values of '$matrix'
'$matrix' = $letters, $numbers
Therefore '$value' = $letters, $numbers
'$array' = key values of '$list'
Therefore '$array' = 'Letter', 'Number'
I know I can type echo "<p>Letter: {$letters[0]}</p>"; to have the letter 'A' returned, but if I type echo "<p>Letter: {$letters}</p>"; then I will receive an error.
My focus is on line 13, { echo "<li>$array [$key] = $value"; }
Why is this not returning an error?
No spot in '$array' was specified, '$key' was never assigned, and no spot in '$value' is specified.
I have only started learning PHP & MySQL a few days ago.
Any help is greatly appreciated as I am trying to learn and want to move on to the next part of this book, but I need to get my head around this first.
~Thanks!
foreach($matrix as $array => $list)
{
//$array is String "Letter" and $list is array $letters for first iteration
//$array is String "Number" and $list is array $numbers for second iteration
echo'<ul>';
foreach($list as $key => $value)
{
//when $list=$letters
//1st iteration:$key =0 and value 'A'; 2nd iteration :$key=1 and $value= 'B'.....
//finally
//$array means "Letter"
//$key mean 0
//$value mean "A"
//and loop goes on
echo "<li>$array [$key] = $value";
//result
//<li>Letter[0] = A;
//<li>Letter[1] = B;
//.............
}
echo '</ul>';
}
Hope you understand.
Remember your li tag is not closed.Use this
echo "<li>$array [$key] = $value </li>";
All three of those variables are ones that have been temporarily defined for the body of a loop by the foreach construct, and each of them are numbers or strings, not arrays.
http://php.net/manual/en/control-structures.foreach.php
foreach($matrix as $array => $list)
The above line defines the variables $array and $list for the body of that loop; $array is a string that is set to each of the keys of $matrix in turn; $list is the corresponding value for each key.
foreach($list as $key => $value)
Similarly, this defines the variables $key and $value within the body of the loop; $key is set to each key of $list one at a time, and $value is set to each matching value.
All of those three variables are scalar values (either strings or numbers), so there's no issue with printing them directly.
foreach($matrix as $array => $list)
Look at how foreach works. Here the not-well-named $array will have one of two values: either "Letter" or "Number". Obviously both of them can be printed without issue.
foreach($list as $key => $value)
Here $list will either be array( 'A', 'B', 'C' ) or ( 1, 2, 3 ). In either case, $key will have one of the values 0, 1 or 2 and $value will be either a string or an integer. Again, all of these can be printed with no problem.
First of all this
echo "<p>Letter: {$letters}</p>";
returns error because you tried to echo whole array. It can't be done with echo.
This code
foreach($list as $key => $value)
{ echo "<li>$array [$key] = $value"; }
echo '</ul>';
}
is valid because every value has it's own key. If you don't define key for some value, then the key will added automatically.
You said you know that this works:
echo "<p>Letter: {$letters[0]}</p>";
"0" is the key and it was added automatically during the array initialization. Key doesn't need to be string to be a key for some value.
I was missing the fact that if no key value was set for '$letters' and '$numbers', their key for each value is their order by default.
So going through each loop I realized that $list[0] = $letters and $list[1] = $numbers
Therefore:
'$value' = non key value of '$list[0]' = non-key value of '$letters'
'$key' = key value of '$list[0]' = key value of '$letters'
So in a sense, '$list' is a pointer to '$letters' and '$numbers' respectively.
If anyone in the future ever gets confused, I have worked out each iteration below:
/*
Loop One:
Sub1:
$list[0] = $letters = 'A', 'B', 'C'
$key = '0'
$value = 'A'
Sub2:
$list[0] = $letters = 'A', 'B', 'C'
$key = '1'
$value = 'B'
Sub3:
$list[0] = $letters = 'A', 'B', 'C'
$key = '2'
$value = 'C'
Loop Two:
Sub1:
$list[1] = $numbers = '1', '2', '3'
$key = '0'
$value = '1'
Sub2:
$list[1] = $numbers = '1', '2', '3'
$key = '1'
$value = '2'
Sub3:
$list[1] = $numbers = '1', '2', '3'
$key = '2'
$value = '3'
*/

PHP Script and max() Value

Sorry for my bad English and thanks for your help in advance! I have kind of a tricky problem I've encountered while coding. Here's the point:
I need a script that essentially extracts the 5 max values of 5 arrays, that are "mixed", i.e. they contain "recurrent" values. Here is an example:
array1(a, b)
array2(a, c, d, e, g)
array3(b, d, g, h)
array4(e, t, z)
array5(b, c, d, k)
The 2 essential requests are:
1) the sum of those 5 arrays (array1+array2+array3...) MUST be the highest possible...
2) ...without repeat ANY value previously used** (e.g. if in array1 the top value was "b", this cannot be re-used as max value in arrays 3 or 5).
Currently I have this...:
$group1 = array(a, b);
$group = array(a, b, c, d);
$max1a = max(group1);
$max2a = max(group2) unset($max1a);
$sum1 = $max1a + $max2a;
$max2b = max(group2);
$max1b = max(group1)
unset($max2b);
$sum2 = $max1b + $max2b;
if($sum1 > $sum2) {
echo $sum1
} else {
echo $sum2
}
... but it's kinda impossible to use this code with 5 arrays, because I should compare 5! (120...!!!) combinations in order to find the max sum value.
I know the problem is quite difficult to explain and to solve, but I really need your help and I hope you can save me!!!
Cheers
I'm adding this as another answer to leave the previous one intact for someone coming across this looking for that variation on this behaviour.
Given the 2 arrays:
$array1 = array(30, 29, 20);
$array2 = array(30, 20, 10);
The maximum sum using one element from each is 59 - this is dramatically different to my previous approach (and the answers' of others) which took the max element of the first array and then the highest element of the next array that is not equal to any previously used value - this would give 50 instead.
The code you want is this:
$mainArray = array();
$mainArray[] = array(30, 29, 20);
$mainArray[] = array(30, 20, 10);
$tempArray = array();
$newArray = array();
foreach($mainArray as $innerArray) {
$newArray = array();
if (count($tempArray) == 0) {
foreach ($innerArray as $value) {
$newArray[] = array('total' => $value, 'used' => array($value));
}
}
else {
foreach ($tempArray as $key => $innerTempArray) {
$placed = FALSE;
foreach ($innerArray as $value) {
if (!(in_array($value, $innerTempArray['used']))) {
$newArray[] = array('total' => $tempArray[$key]['total'] + $value, 'used' => $tempArray[$key]['used']);
$newArray[count($newArray) - 1]['used'][] = $value;
$placed = TRUE;
}
}
if (!($placed)) {
echo "An array had no elements that had not already been used";
die();
}
}
}
$tempArray = $newArray;
}
$total = 0;
if (count($newArray) == 0) {
echo "No data passed";
die();
}
else {
$total = $newArray[0]['total'];
}
for ($i = 0; $i < count($newArray); $i++) {
if ($newArray[$i]['total'] > $total) {
$total = $newArray[$i]['total'];
}
}
var_dump($total);
EDIT - Do not repeat used variables (but repeated values are ok):
Let
//$a = 30, $b = 30, $c = 25, $d = 20, $e = 19
$array1 = array($a, $c, $d);
$array2 = array($b, $d, $e);
We want to choose $a from $array1 and $b from $array2 as these give the largest sum - although they're values are the same that is allowed because we only care if the names of the variables saved to that place are the same.
With the arrays in the above format there is no way of achieving the desired behaviour - the arrays do not know what the name of the variable who's value was assigned to their elements, only it's value. Therefore we must change the first part of the original answer to:
$mainArray[] = array('a', 'c', 'd');
$mainArray[] = array('b', 'd', 'e');
and also have either the of the following before the first foreach loop (to declare $a, $b, $c, $d, $e)
//either
extract(array(
'a' => 30,
'b' => 30,
'c' => 25,
'd' => 20,
'e' => 19
));
//or
$a = 30; $b = 30; $c = 25; $d = 20; $e = 19;
The above both do exactly the same thing, I just prefer the first for neatness.
Then replace the line below
$newArray[] = array('total' => $value, 'used' => array($value));
with
$newArray[] = array('total' => ${$value}, 'used' => array($value));
The change is curly brackets around the first $value because that is then evaluated to get the variable name to use (like below example):
$test = 'hello';
$var = 'test';
echo ${$var}; //prints 'hello'
A similar change replaces
$newArray[] = array('total' => $tempArray[$key]['total'] + $value, 'used' => $tempArray[$key]['used']);
with
$newArray[] = array('total' => $tempArray[$key]['total'] + ${$value}, 'used' => $tempArray[$key]['used']);
Now the code will function as wanted :)
If you are dynamically building the arrays you are comparing and can't build the array of strings instead of variables then there is no way to do it. You would need some way of extracting "$a" or "a" from $a = 30, which PHP is not meant to do (there are hacks but they are complicated and only work in certain situations (google "get variable name as string in php" to see what I mean)
If by the top value you mean the first alphabetically then the following would work:
$array1 = array('a', 'b');
$array2 = array('a', 'c', 'd', 'e', 'g');
$array3 = array('b', 'd', 'g', 'h');
$array4 = array('e', 't', 'z');
$array5 = array('b', 'c', 'd', 'k');
$mainArray = array($array1, $array2, $array3, $array4, $array5);
foreach ($mainArray as $key => $value) {
sort($mainArray[$key]);
}
$resultArray = array();
foreach($maniArray as $key1 => $value1) {
$placed = FALSE;
foreach ($value1 as $value2) {
if (!(in_array($value2, $resultArray))) {
$resultArray[] = $value2;
$placed = TRUE;
break;
}
}
if (!($placed)) {
echo "All the values in the " . ($key + 1) . "th array are already max values in other arrays";
die();
}
}
var_dump($resultArray);
I'm not sure, of i really understood your problem correctly, these are my assumptions:
You have five arrays containing numbers
These numbers can occur multiple times across the arrays
You want to find the highest possible sum of elements across your arrays
The sum uses one single value of each array
But the sum must not use the same number twice
Is that correct?
If Yes, then:
The highest possible sum across all arrays is always the sum of the largest elements. If you do not want to use the same number twice, you can just get the maximum from the first array, remove it from all the others and then sum up all the remaining maxima.
Like so:
$arrays = array();
$arrays[] = array(1, 2);
$arrays[] = array(1, 3, 4, 5, 7);
$arrays[] = array(2, 4, 7, 8);
$arrays[] = array(5, 20, 26);
$arrays[] = array(2, 3, 4, 11);
for($i=0, $n=count($arrays); $i<$n; $i++) {
if($i===0) {
$a1max = max($arrays[$i]);
$sum = $a1max;
} else {
$duplicate_pos = array_search($a1max, $arrays[$i]);
if($duplicate_pos !== FALSE) {
unset($arrays[$i][$duplicate_pos]);
}
$sum += max($arrays[$i]);
}
}
echo "sum: " . $sum . "\n";
Assuming you have grouped together all your values in one array like this,
$array = array(
array(1,2,3),
array(1,2,3,4),
array(1,2,3,4,5,6),
array(1,2,3,4,5,6),
array(1,2,3,4,5,6,7)
);
Loop through $array, and get the highest value which has not been used previously,
$max = array();
foreach($array as $value)
$max[] = max(array_diff($value, $max));
Calculate the sum of all values with array_sum(),
echo "The maximal sum is: ".array_sum($max);

How to use multiple arrays in " single " foreach() loop [duplicate]

This question already has answers here:
Two arrays in foreach loop
(24 answers)
Closed 7 years ago.
I'm trying to echo out all variables of two arrays with a single foreach loop making a url. Some coding examples will be honored.
I have this so far :
<?php
foreach($menu_names as $menu_name){
echo "<li><a href='?subj= " .urlencode($subjects["id"]). " '>".$menu_name."</a></li>";
}
?>
I want to add one more array within this loop
assume you have the same number of items in those two arrays.
if you want to use foreach(), then the arrays need to have the same index:
foreach ($a as $index => $value)
{
echo $a[$index] .' '. $b[$index];
}
if the arrays have numeric index, you can just use for():
for ($i = 0; $i < sizeof($a); $i++)
{
echo $a[$i] .' '. $b[$i];
}
array_combine() will merge your 2 arrays into one with key=>value pairs and then access them through foreach statement
e.g
foreach(array_combine($a,$b) as $key=>$value) {
echo $key."<br/>".$value;
}
The answer depends on what exactly you need to do with the arrays and how you need to do it.
If your arrays have similar indexes, and you need to use the same element from each array, you could do like
foreach ($array1 as $index => $value1) {
$value2 = $array2[$index];
// do stuff with $value1 and $value2 here
}
(Although in this case, particularly if you find yourself doing this a lot, you may want to think about using a single array of either objects or arrays, so that the data will always be together and easier to connect.)
Or, if the arrays have the same type of elements in it and you want to iterate over both in order, you could iterate over array_merge($array1, $array2). (If the arrays aren't numerically indexed, though, and particularly if they have the same stringy keys, one of the arrays' elements could replace the other. See the docs on array_merge for details.)
There are a bunch of other possibilities, depending on how you need the elements. (The question really doesn't provide any info on that.)
Full Code:
1)
<?php
$First = array('a', 'b', 'c', 'd');
$Second = array('1', '2', '3', '4');
foreach($First as $indx => $value) {
echo $First[$indx].$Second[$indx];
echo "<br />";
}
?>
or 2)
<?php
$First = array('a', 'b', 'c', 'd');
$Second = array('1', '2', '3', '4');
for ($indx = 0 ; $indx < count($First); $indx ++) {
echo $First[$indx] . $Second[$indx];
echo "<br />";
}
?>

Categories