I'm having a hard time wrapping my head around this one. I have an array with different keys/values, I want to do a loop that allows me to put in different code wrappings. I'm working with an array that I'm trying to get as an XML.
This is an example of what I have..
I have what came with the code commented out and what I'm trying to do just below it in the foreach
// Multidimensional array
$superheroes = array(
"spider-man" => array(
"name" => "Peter Parker",
"email" => "peterparker#mail.com",
),
"super-man" => array(
"name" => "Clark Kent",
"email" => "clarkkent#mail.com",
),
"iron-man" => array(
"name" => "Harry Potter",
"email" => "harrypotter#mail.com",
)
);
// Printing all the keys and values one by one
$keys = array_keys($superheroes);
for($i = 0; $i < count($superheroes); $i++) {
echo $keys[$i] . "{<br>";
foreach($superheroes[$keys[$i]] as $key => $value) {
// echo $key . " : " . $value . "------";
echo '<wp:meta_key>'.$value['email'].'<wp:meta_key>';
echo '<wp:meta_value><![CDATA['.$value['name'].']]></wp:meta_value>';
}
echo "}<br>";
}
This is how you iterate the array, two levels deep:
foreach($superheroes as $key => $hero) {
echo $key."\n";
foreach ($hero as $heroKey => $heroValue) {
echo "\t".$heroKey."=>".$heroValue."\n";
}
}
You will have to adjust it to your output, but im showing the concept. The first foreach iterates all the heroes, and the second foreach iterates all the key/value pairs of each hero
EDIT: Hold on, its a bit unclear what you actually want. Is this what you want?
foreach($superheroes as $key => $hero) {
echo $key."\n";
echo "\t".$hero['email']."\n";
echo "\t".$hero['name']."\n";
}
Related
I have an array thusly
$main_array = [
["image" => "james.jpg", "name" => "james", "tag" => "spacey, wavy"],
["image" => "ned.jpg", "name" => "ned", "tag" => "bright"]
["image" => "helen.jpg", "name" => "helen", "tag" => "wavy, bright"]
]
I use a foreach to echo some HTML based on the value of tag. Something like this
foreach($main_array as $key => $array) {
if ($array['tag'] == "bright") {
echo '<p>'.$array['name'].' '.$array['image'].' '.$array['tag'].'</p>';
}
}
This only outputs "ned" as matching the tag "bright". But it should output "helen" too. Similarly:
foreach($main_array as $key => $array) {
if ($array['tag'] == "wavy") {
echo '<p>'.$array['name'].' '.$array['image'].' '.$array['tag'].'</p>';
}
}
Should output "james" and "helen". What kind of function do I need to achieve the desired result?
When checking an item in a list of items, you can use explode() to split it into parts (I've used split by ", " as each item seems to have a space as well) and then use in_array() to check if it is in the list...
if (in_array("bright", explode( ", ", $array['tag']))) {
You cant do it directly, because it return key with values in string. Below are the working code.
<?php
$main_array = [
["image" => "james.jpg", "name" => "james", "tag" => "spacey, wavy"],
["image" => "ned.jpg", "name" => "ned", "tag" => "bright"],
["image" => "helen.jpg", "name" => "helen", "tag" => "wavy, bright"]
];
foreach($main_array as $key => $array) {
$str_arr = explode (", ", $array['tag']);
foreach ($str_arr as $key2 => $array2) {
if ($array2 == "wavy") {
echo '<p>'.$array['name'].' '.$array['image'].' '.$array['tag'].'</p>';
}
}
}
?>
How to get the distinct keys ($key) and multiple different values ($myObjectValues) in list of objects?
My expected outcome is distinct keys displays as column in table and its different values display as multiple rows. The column ($key) should not be hardcore and I plan to display in blade view.
Ideal:
Current Code:
foreach($x as $key => $item) {
print_r($key); //this is list number
foreach($item as $key => $myObjectValues){
print_r($key); //this is my object key
print_r($myObjectValues); //this is my object values
}
}
This is the json array object ($x).
Array(
[0] => stdClass Object
(
[milk_temperature] => 10
[coffeebean_level] => 124.022
)
[1] => stdClass Object
(
[milk_temperature] => 1099
[soya_temperature] => 10
[coffeebean_level] => 99.022
)
[2] => stdClass Object
(
[milk_temperature] => 1099
[coffeebean_level] => 99.022
)
)
You can do it like this, it's not the best approach in the world but it works and you can use it as an example. First you create a list with the table header titles and then start by printing the header and then the values.
<?php
$x = [
(object) [
'milk_temperature' => 10,
'coffeebean_level' => 124.022
],
(object) [
'milk_temperature' => 1099,
'soya_temperature' => 10,
'coffeebean_level' => 99.022
],
(object) [
'milk_temperature' => 1099,
'coffeebean_level' => 99.022
]
];
// list all the keys
$keys = [];
foreach($x as $key => $item) {
$keys = array_merge($keys, array_keys((array) $item));
}
$keys = array_unique($keys);
// echo the header
foreach ($keys as $key) {
echo $key . ' ';
}
echo "\n";
// echo the values
foreach($x as $item) {
foreach ($keys as $key) {
echo $item->$key ?? '-'; // PHP 7+ solution
// echo isset($item->$key) ? $item->$key : '-'; // PHP 5.6+
echo ' ';
}
echo "\n";
}
You can first get the keys of the array with array_keys() and array_collapse():
$columns = array_keys(array_collapse($records));
Then you look through the $records using the same loop you already have. Let's demo it with this example:
$columns = array_keys(array_collapse($records));
foreach($records as $key => $item) {
//these are each record
foreach ($columns as $column) {
//each column where you build the header
// converts $item to an array
$item = (array)$item;
if (! array_key_exists($column, (array)$item)) {
// show '---'
echo '---';
continue;
}
//show $item[$item]
echo $item[$column];
}
}
The great advantage of doing so i.e getting the columns first (apart from converting the stdClass to an array) is that the columns array can be used any way you deem fit.
It would be more beneficial if you can have your data all as array then you can easily use the array functions available on it.
I'm having trouble pulling out the key value pairs in only one sub array of a two dimensional array.
I'm trying to get it in the following format:
"Insect: b: beetle
Insect: m: moth
etc..."
here is what I've got so far:
$animals = array(
'insect' => array('b'=>"beetle", 'm'=>"moth", 's'=>"spider"),
'mammal' => array('d'=>"dolphin", 'h'=>"human", 'c'=>"chimp"),
'fish' => array('a'=>"angler", 'sh'=>"shark", 'p'=>"puffer"));
echo $animals['insect']; // trying to print sub array??
echo "<pre>";
foreach($animals as $Mkey => $domains)
foreach($domains as $key => $species)
echo "$Mkey: $key : $species<br>"; //prints whole array
foreach($animals['insect'] as $Mkey => $species) {
echo "$Mkey : $species<br>";
}
// dynamic key:
$key = 'insect';
foreach($animals[$key] as $Mkey => $species) {
echo "$key: $Mkey : $species<br>";
}
How Do I access the innermost array? the grade is giving me a Notice: Array to string conversion in /scripts/array.php on line 34
grade: Array
$data = array();
$data[0] = 78;
$data[1] = 34;
$data[2] = 87;
$student = array(0 => array(
"Stdno" => "212",
"name" => "Lorem Ipsum",
"subject" => "Networking",
"grade" => $data
),
1 => array(
"Stdno" => "212",
"name" => "Jimmy Shu",
"subject" => "Informatics",
"grade" => $data
),
2 => array(
"Stdno" => "212",
"name" => "Amet Dolor",
"subject" => "Discrete Combinatorics",
"grade" => $data
)
);
foreach ($student as $key => $value) {
foreach ($value as $key => $value) {
echo "<b>{$key}</b>: {$value}";
echo "<br />";
}
echo "<br />";
}
First of all, you should really not use $key and $value again (in fact, I thought foreach ($value as $key=>$value) didn't work).
Assuming you want to echo the $data element at the same position than in your $student array (i.e. echo $data[0] for $student[0]), you should use the first key :
foreach ($student as $key => $value) {
foreach ($value as $key2 => $value2) {
echo "<b>{$key2}</b>: ";
if ($key2 == 'grade')
echo $value2[$key];
else
echo $value2;
echo "<br />";
}
echo "<br />";
}
First, just a comment please avoid using same keys on foreach. like in your $value.
To fix your issue, it clearly says, it's an array but you try to echo it, you could try to use this instead.
echo "<b>{$key}</b>: " . json_encode($value);
As stated by #roberto06 you should avoid using same variables for cycles that are nested. Those variables will be overwriten by new values.
To the question:
You could check wether $value is string or array
is_array($val) || is_string($val)
based on result you could write another foreach cycle or print string.
in your second foreach you are foreaching this array:
array(
"Stdno" => "212",
"name" => "Lorem Ipsum",
"subject" => "Networking",
"grade" => $data
)
so the (second) $key will be "Stdno", "name", "subject", "grade"
and values will be "212", "Lorem Ipsum", "Networking" (those are strings) and $data (this is array)
to print this array, you need to create new foreach and use it only when $key == "grade" or use implode on it:
if($key == "grade"){
$i = implode(', ', $value);
//print or something
}
I have an array that looks like this:
$rowarray(
[0] => [PID] => 97162 [TID] => 340 [StatsID] => 49678
[1] => [PID] => 97165 [TID] => 340 [StatsID] => 49673
[2] => [PID] => 97167 [TID] => 340 [StatsID] => 49675
[3] => [PID] => 97162 [TID] => 340 [StatsID] => 49679
)
Then my code looks like this:
$cntr=0;
foreach($rowarray as $row)
{
echo "<tr><td>$row[PID] $row[TID] $row[StatsID] </td></tr>";
$cntr++;
}
Two things I want to do I want to be able not print the duplicates in the array but print the additional column that has a different value. So my desired output would look like this.
97162 340 49678 49679
97165 340 49673
97167 340 49675
I started out with the array_unique() but that only returned:
97162 340 49678
Assuming only the StatsID changes (not clear from the question)
$map = array();
foreach($rowarray as $row){
$k = $row["PID"] . '-' . $row["TID"];
if( !isset( $map[$k] ) ){
$map[$k] = array();
}
array_push( $map[$k], $row["StatsId"] );
}
foreach($map as $k=>$v){
$row = explode( '-', $k );
echo "<tr><td>$row[0] $row[1] " . implode( " ", $v ) . " </td></tr>";
}
Here's what I'd do:
Start by sorting the array (using usort to sort by PID, then by TID)
Initialize "last" variables ($last_PID and $last_TID). They will store the respective values in the loop
In the loop, first compare the "current" variables to the "last" ones, if they're the same then just echo the StatsID value.
If they're not the same, output the <tr> (but not the final </tr>, so the first part of the loop can add more StatsID values if necessary)
Still inside the loop, after outputting everything, update the "last" variables.
After the loop, output the final </tr>
This may not be optimal, but I'm pretty sure it'll work.
Transfer the $rowarray structure into a map of maps of arrays, like this:
$rowarray = array(
array('PID' => 97162, 'TID' => 340, 'StatsID' => 49678),
array('PID' => 97165, 'TID' => 340, 'StatsID' => 49673),
array('PID' => 97167, 'TID' => 340, 'StatsID' => 49675),
array('PID' => 97162, 'TID' => 340, 'StatsID' => 49679)
);
$keys = array();
foreach ($rowarray as $row) {
if (!is_array(#$keys[$row['TID']])) {
$keys[$rowarray['TID']] = array();
}
if (!is_array(#$keys[$row['TID']][$row['PID']])) {
$keys[$row['TID']][$row['PID']] = array();
}
$keys[$row['TID']][$row['PID']][] = $row['StatsID'];
}
foreach ($keys as $pid => $pid_arr) {
foreach ($pid_arr as $tid => $tid_arr) {
echo "<tr><td>$tid $pid " . implode(' ', $tid_arr) . "</td></tr>";
}
}
See this code in action
As far as I can tell, the only way to do this would be to loop through the array creating a new unique array as you go.
$unique = array();
foreach ($row as $value)
{
$key = $value['PID'];
if (isset($unique[$key]))
{
$unique[$key]['StatsID'] .= ' ' . $value['StatsID'];
}
else
{
$unique[$key] = $value;
}
}
Now, $unique would give you the results you're looking for and you can loop through the unique array and output your results (I also added your counter if needed):
$count = count($unique);
foreach ($unique as $row)
{
echo "<tr><td>{$row['PID']} {$row['TID']} {$row['StatsID']} </td></tr>";
}