How do I use the PHP foreach() function? [duplicate] - php

This question already has answers here:
Group subarrays by one column, make comma-separated values from other column within groups
(2 answers)
Closed 4 months ago.
I have this situation: multiple option names and multiple option values. How do I display foreach option name all the values?
My code does this:
Roses (option name) are red (option value)
Roses are blue
Roses are white
How I want it to display like this:
Roses are red, blue, white
Here's my current code:
<?php
foreach ($product['option'] as $option) { ?>
- <small>
<?php echo $option['name']; ?>
are
<?php echo $option['value']; ?></small><br />
<?php } ?>

Here's an option.
Your initial array (this is probably grabbed from a database. I'm kind of guessing the exact structure based on your question, but should be close):
/* Initial array
Array
(
[option] => Array
(
[0] => Array
(
[name] => Roses
[value] => red
)
[1] => Array
(
[name] => Violets
[value] => blue
)
[ ... ]
)
)
*/
Loop through it and make it into an array with each value holding an array of colors. Basically grouping $values on their $name. This is pretty handy also because it doesn't matter if your database entries are out of order.
// Loop all $product['option']
foreach ($product['option'] as $option) {
// If we don't have an array made for this $name, make one
if (!is_array( $products[ $option['name'] ] ) )
$products[ $option['name'] ] = array();
// Add the $value to the $name's array
$products[ $option['name'] ][] = $option['value'];
}
/* $products =
Array
(
[Roses] => Array
(
[0] => red
[1] => blue
[2] => white
)
[Violets] => Array
(
[0] => blue
[1] => white
)
)
*/
Next it's just a matter of sentence structure, combining it all together. Since you have a handy array, you can also do a multitude of other forms of output quickly - this is just for your sentence question.
// Loop the new array of name=>array(vals)
foreach($products as $name => $value){
// Counter variables and initial values for output
$cnt = count($value);
$cur = 2;
$out = $name . " are ";
// Loop all $values for the current $name
foreach($value as $v){
// Make the output
$sep = ($cur > $cnt ? "."
: ($cnt == 2 || $cur == $cnt ? " and " : ", ") );
$out .= $v . $sep;
$cur++;
}
// Save the output to the name array
$products[$name]["out"] = $out;
}
This output can be used now anywhere you can access the $products array
echo $products["Roses"]["out"];
echo $products["Violets"]["out"];
/*
Output:
Roses are red, blue and white.
Violets are blue and white.
*/
http://codepad.org/sL8YhzCq

If I understand your code, you could do:
Roses are
<?php
foreach ($product['option'] as $option) {
echo "$option['value'], ";
}
?>
(Maybe change the change 'Roses', but I don't know where this name would be in you code.)

Just store the $option['name'] and test if it's the same as the previous iteration:
<?php
$previous = null;
foreach ($product['option'] as $option) {
if ($option['name'] == $previous) {
echo ", {$option['value']}";
}
else {
if ($previous)
echo "</small><br/>";
?>
- <small><?php echo $option['name']; ?> are
<?php echo $option['value'];
}
$previous = $option['name'];
}
echo "</small><br/>"; ?>
My code is a bit messy and not tested, but I guess you get the idea :)

Related

Compare two array_count_values array - keys and values - PHP

I am counting the elements of an array and storing the result in an array using array_count_values.
Let's consider this is the output for this instance, which is created from an array, which was in-turn created with the help of explode.
magazine = Array(
[avatar] => 1
[essence] => 6
[pie] => 1
[multiplex] => 1
[bill] => 2
[nice] => 2
[pie ] => 1
)
ransom = Array(
[multiplex] => 1
[pie] => 2
[avatar] => 3
[bill] => 1
[nice] => 3
[essence] => 1
)
Now, I want to check if the elements in Array ransom are available in array Magazine.
The loop should exit if the element in ransom is not available in magazine. (or) If the element exists, value of that element in ransom cannot be greater than the same element value in magazine.
How can I achieve this? How to use nested foreach in this case? as I cannot use a simple for loop here because of the keys.
$ransom_temp = "avatar essence pie multiplex bill nice essence nice bill essence essence essence essence pie"
$magazine_temp = "multiplex pie pie avatar bill nice nice nice avatar essence avatar"
$magazine = explode(" ",$magazine_temp);
$ransom = explode(" ",$ransom_temp);
$countRan = array_count_values($ransom);
$countMag = array_count_values($magazine);
print_r($countMag);
print "<br>";
print_r($countRan);
if($n > $m){
print "No";
return;
}
foreach($countRan as $key1=>$value1){
foreach($countMag as $key2=>$value2)
if($key1 != $key2) || $value1 > $value2){
print "No";
return;
}
}
print "Yes";
You only need one loop:
$ransom_temp = "avatar essence pie multiplex bill nice essence nice bill essence essence essence essence pie"
$magazine_temp = "multiplex pie pie avatar bill nice nice nice avatar essence avatar"
$magazine = explode(" ",$magazine_temp);
$ransom = explode(" ",$ransom_temp);
$countRan = array_count_values($ransom);
$countMag = array_count_values($magazine);
print_r($countMag);
print "<br>";
print_r($countRan);
if(count($countRan) > count($countMag)) {
print "No";
return;
}
foreach ($countRan as $key => $value){
// exit if key not exists in $countMag array
// or exit if value in $countRan[$key] greater than $countMag[$key]
if (!array_key_exists($key, $countMag) || $value > $countMag[$key]) {
print "No";
return;
}
}
print "Yes";

how to modify array_count_values output

i have an array
$array=(1,1,2,3,3,3,4);
i need to find each element how many times each element is exist in array .
So that i use
$occurences = array_count_values($array);
output is
Array
(
[1] => 2
[2] => 1
[3] => 3
[4] => 1
)
But i need to arrage the out put in following format
1 : 2
2 : 1
3 : 3
4 : 1
how can i do that ?
is there an other solution rater than using array_count_values
please help ;
Use foreach to iterate over every occurance and echo them out.
// If they are in wrong order, sort your array
ksort($occurences);
// Print output
if(count($occurences)>0){
foreach ($occurences as $key => $value) {
echo $key.' : '.$value.'<br />';
}
}
EDIT
To sort by no of occurances, use arsort.
arsort($occurences);
Of course, before printing it.
If 2:1 must come before 4:1 in your case, use:
asort($occurences);
arsort($occurences);
Just use this loop to have output like you need
foreach ($occurences as $k => $v) {
echo "$k : $v <br>";
}
You can use json_encode or array_keys and array_values
<?php
$array= array(1,1,2,3,3,3,4);
$occurences = array_count_values($array);
$array_keys = array_keys($occurences);
$array_values = array_values($occurences);
for($i=0; $i<count($array_keys); $i++) {
echo $array_keys[$i].':'.$array_values[$i].'\n';//add \n or \br tag
}
//you can echo json_encode
echo json_encode($occurences);

PHP - Use everything from 1st array, remove duplicates from 2nd?

I have 2 arrays - the first one is output first in full. The 2nd one may have some values that were already used/output with the first array. I want to "clean up" the 2nd array so that I can output its data without worrying about showing duplicates. Just to be sure I have the terminology right & don't have some sort of "array within an array", this is how I access each one:
1st Array
$firstResponse = $sth->fetchAll();
foreach ($firstResponse as $firstResponseItem) {
echo $firstResponseItem['samecolumnname']; // Don't care if it's in 2nd array
}
2nd Array
while( $secondResponseRow = $dbRequest->fetch_assoc() ){
$secondResponseArray = array($secondResponseRow);
foreach ($secondResponseArray as $secondResponseItem){
echo $secondResponseItem['samecolumnname']; //This can't match anything above
}
}
Thanks!
For example:
$response_names = array();
$firstResponse = $sth->fetchAll();
foreach ($firstResponse as $firstResponseItem)
$response_names[] = $firstResponseItem['samecolumnname'];
while( $secondResponseRow = $dbRequest->fetch_assoc() ){
$secondResponseArray = array($secondResponseRow);
foreach ($secondResponseArray as $secondResponseItem) {
if (!in_array($secondResponseItem['samecolumnname'], $response_names))
$response_names[] = $secondResponseItem['samecolumnname'];
}
}
array_walk($response_names, function($value) { echo $value . '<br />' });
If I understand what you're looking to do and the arrays are in the same scope, this should work.
$secondResponseArray = array($secondResponseRow);
$secondResponseArray = array_diff($secondResponseArray, $firstResponse);
//secondResponseArray now contains only unique items
foreach ($secondResponseArray as $secondResponseItem){
echo $secondResponseItem['samecolumnname'];
}
If you know that the keys of duplicate values will be the same you could use array_diff_assoc to get the items of the first array that aren't in the other supplied arrays.
This code
<?php
$a = array('abc', 'def', 'ghi', 'adg');
$b = array('abc', 'hfs', 'toast', 'adgi');
$r = array_diff_assoc($b, $a);
print_r($a);
print_r($r);
produces the following output
[kernel#~]php so_1.php
Array
(
[0] => abc
[1] => def
[2] => ghi
[3] => adg
)
Array
(
[1] => hfs
[2] => toast
[3] => adgi
)
[kernel#~]

Nested foreach with arrays - php

The problem I am facing is when I use one foreach inside another and the array of the first foreach has more than 1 entries. What I want to do is to exclude all entries of array 1 from array 2. I've been on almost all related posts, cannot solve it by myself, I need a little help if possible. Sorry for my bad English.
Example:
$choice ---> array with random number of entries each time (for this example 2)
Example:
/var/www/clients/client1/web1/web/images,/var/www/clients/client1/web1/web/tmp
$list ---> array of random number of entries each time (for this example 10000)
Example:
/var/www/clients/client1/web1/web/images,/var/www/clients/client1/web1/web/tmp,/var/www/clients/client1/web1/web/includes,/var/www/clients/client1/web1/web/libraries,......
$list has always more entries than $choice
And I have this code here:
foreach ( $choice as $select )
{
foreach ( $list as $file )
{
if ( (strpos( $file, $select )) !== false )
{
// exclude this
}
else
{
// include this
}
}
}
What the above code will do (unfortunately) is:
Step 1. Will compare $select entry-1 with all $file entries.
Step 2. Will exclude $select entry-1 from all $file entries and will include the $select entry-2.
Step 3. Will compare $select entry-2 with all $file entries.
Step 4. Will exclude $select entry-2 from all $file entries and will include the $select entry-1.
Result:
Nothing excluded.
Any help truly appreciated. I am on this for like a week, all I have tried is putting them inside out I am out of ideas.
Thank you.
I believe you're trying to remove items that are in $list from $choice. (Or is it the other way around?) Have you tried the array_diff function? This will work if items in both array are equal. For example:
<?php
//Option 1: array_diff
$bigger = array("A", "B", "C", "D", "E", "F");
$smaller = array("A", "B");
$result = array_diff($bigger, $smaller);
print_r($result);
If you need to do additional processing on the removed items, you can try in_array, but this requires item equality (like above). For example:
//Option 2: in_array (only one foreach loop)
foreach ($smaller as $key => $item) {
if (in_array($item, $bigger)) {
//do something to "remove" it, for example:
unset($smaller[$key]);
unset($bigger[$key]);
//...
}
}
print_r($smaller);
print_r($bigger);
Lastly, if the items in both arrays are not guaranteed to be strictly equals, you could use a double foreach. You'll need to flag items in the inner loop and process them in the outer loop. For example:
//Option 3: double-foreach (items not strictly equals)
$choice = array(
"/var/www/clients/client1/web1/web/images",
"/var/www/clients/client1/web1/web/tmp"
);
$list = array(
"/var/www/clients/client1/web1/web/images",
"/var/www/clients/client1/web1/web/tmp",
"/var/www/clients/client1/web1/web/includes",
"/var/www/clients/client1/web1/web/libraries",
// more items
);
foreach ($choice as $choice_key => $choice_item) {
$exists_in_list = FALSE;
foreach ($list as $list_key => $list_item) {
if (strpos($list_item, $choice_item) !== FALSE) {
//$choice_item is string-contained inside $list_item:
$exists_in_list = TRUE;
//Do some processing on $list (while "$list_key" is in scope). For example:
unset($list[$list_key]); //removes the matching items from $list
//...
break;
}
}
if ($exists_in_list) {
//Do post-processing on $choice. For example:
unset($choice[$choice_key]); //removes the matching items from $choice
//...
}
}
echo '$choice is now ';
print_r($choice);
echo '$list is now ';
print_r($list);
The $result is:
//Option 1:
Array //$result == $bigger - $smaller
(
[2] => C
[3] => D
[4] => E
[5] => F
)
//Option 2:
Array //$smaller - $bigger
(
)
Array //$bigger - $smaller
(
[2] => C
[3] => D
[4] => E
[5] => F
)
//Option 3:
$choice is now Array
(
)
$list is now Array
(
[2] => /var/www/clients/client1/web1/web/includes
[3] => /var/www/clients/client1/web1/web/libraries
)

Getting Data From Multi-level Array

Question below.
This is the solution I came up with based on Pixeler's answer.
<?php
$i = 0;
foreach ($array as $k1 => $v1) {
if (is_array($v1)) {
echo $k1."<br />";
foreach ($v1 as $k2 => $v2) {
echo "--".$k2."<br />----".$v2."<br />";
}
$i++;
}
echo "<br /<br />";
}
?>
<?php
$array = array( "Apples" => array("Red" => "$2.95", "Green" => "$2.45"),
"Oranges" => array("Navel" => "$4.95"),
"Grapes" => array("Purple" => "$3.75", "Green" => "$3.25")
);
?>
Is it possible to take what's above and get the text for each value by calling a number?
How could I do something like this?...
<?php
echo $array[0];
//Outputs "Apples"
echo $array[0][0];
//Outputs "Red"
echo $array[0][0][0];
//Outputs "$2.95"
echo $array[3][2][1];
//Outputs "$3.25" (Grapes > Green > Price)
?>
EDIT: The idea is that I can return the first level (Apples, Oranges, Grapes), second level (Red, Green, Navel, Purple, Green), and third level ($2.95, $2.45, $4.95, $3.75, $3.25) by calling a number.
For example, I want to do something like this:
<?php
count($array); //returns 3 (Apples, Oranges, Grapes)
//Do some for/foreach function that will produce the following:
//Apples
//->Red: $2.95
//->Green: $2.45
//Oranges
//->Navel: $4.95
//Grapes
//Purple: $3.75
//Green: $3.25
//I'm hoping to structure the code like this:
foreach($i = 0; $i =< count($array); $i++){
//echo title of array (Apples)
//echo each child key and it's value (Red: $2.95; Green: $2.45)
foreach($secondcounter = 0; $secondcounter =< count($array[$i]); $secondcounter++){
echo array_key($array[$i][$secondcounter]) . ": " .$array[$i][$secondcounter];
//Note: I don't actually know if array_key does the trick or not, it's meant to return "Red" in this case, while the non array_key()'d is meant to return the price of red apples, $2.95
}
?>
EDIT: It is important to note that I cannot use words to call the data. I must use numbers, i.e. [0] to call the first item in the array, because Apples could change depending on what row of data I load from my database. In other words... Apples could actually turn out to be Books, and Red could turn out to be the name of the book => price.
I'm intending on using serialize/unserialize to store and retrieve the data from the database, although I'm not overly familiar with these functions, I had a brief look at them and they seem reasonably easy to use.
I've been researching for hours but I cant find anything.
It is vital that I am able to call the data by numbers, not text. So $array["Apples"] is unacceptable.
I have also looked at json_decode and serialize/unserialize, and I think I get the basic idea of them from a brief look... but I think my main issue is understanding how to call the above data as presented in my example. Any help would be really great.
This is the solution I came up with based on #Pixeler's answer.
<?php
$i = 0;
foreach ($array as $k1 => $v1) {
if (is_array($v1)) {
echo $k1."<br />";
foreach ($v1 as $k2 => $v2) {
echo "--".$k2."<br />----".$v2."<br />";
}
$i++;
}
echo "<br /<br />";
}
?>
What about this one?
array_search("Apples",array_keys($array));
If you want to loop your array one way or another you might have to create new array, loop through your old array and create new numeric array array?
FIRST WAY
$array = array( "Apples" => array("Red" => "$2.95", "Green" => "$2.45"),
"Oranges" => array("Navel" => "$4.95"),
"Grapes" => array("Purple" => "$3.75", "Green" => "$3.25")
);
$newArray = array();
foreach ($array as $value) {
$newArray[] = (is_array($value)) ? array_values($value) : $value;
}
echo '<pre>';
var_dump($newArray);
echo '</pre>';
SECOND WAY
$array = array( "Apples" => array("Red" => "$2.95", "Green" => "$2.45"),
"Oranges" => array("Navel" => "$4.95"),
"Grapes" => array("Purple" => "$3.75", "Green" => "$3.25")
);
$newArray = array();
$i = 0;
foreach ($array as $key => $value) {
if (is_array($value)) {
$newArray[$i] = array();
foreach ($value as $k => $v) {
$newArray[$i][] = $v;
}
$i++;
}
}
echo '<pre>';
var_dump($newArray);
echo '</pre>';
echo $newArray[0][0];
Obviously I will recommend first way.

Categories