I have an array of multiple arrays all with different levels. What im trying to do is loop though the array by key, and it will go through each level getting the values for those keys. myArray looks something like this
Array ( [0] =>
Array ( [Date] => 2011-15-22
[Color] => blue
[Status] => Fresh
[1] =>
Array ( [Date] => 1999-08-04
[Color] => green
[Status] => Rotten) )
I have tried
foreach($myArray as $row){
foreach($row["Date"] as $k){
echo $k
}
}
I am getting an
Notice: Undefined index: Date
and
Warning: Invalid argument supplied for foreach()
Simply with array_walk_recursive function:
$arr = [
[ 'Date' => '2011-15-22', 'Color' => 'blue', 'Status' => 'Fresh' ],
[ 'Date' => '1999-08-04', 'Color' => 'green', 'Status' => 'Rotten' ]
];
array_walk_recursive($arr, function($v, $k){
if ($k == 'Date') echo $v . PHP_EOL;
});
The output:
2011-15-22
1999-08-04
On your foreach, you should specify the key and value so you can access both:
foreach ($myArray as $key => $value){
echo $key.' is '. gettype ($value).'<br>';
if (is_array($value)){
foreach ($value as $subKey => $subValue){
echo $subkey . ' => ' . $subValue . '<br>';
}
}
}
This way you can access and print all values without losing the structure
As axiac states in the comments, $row["Date"]is a String and therefore not iterable. You probably just want this:
foreach($myArray as $row){
foreach($row as $k){
echo $k
}
}
The Notice Undefined index: Date also describes what is going wrong - you are accessing the index without checking if it exists. It does look like that your data structure is not always the same. In this case you should always check the existence with the isset function:
if (isset($row["Date"])) {
//do something here
}
It looks like you just need this:
foreach($myArray as $row){
echo $row["Date"];
}
or
foreach($myArray as $row){
$k= $row["Date"];
//do stuff...
}
or
foreach($myArray as $row){
$k[]= $row["Date"];
}
// do stuff with $k[] array.
Warning: Invalid argument supplied for foreach()
Because $row["Date"] is string
foreach() - foreach works only on arrays and objects, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable.
Notice: Undefined index: Date
Probably your array may not have element with key Date somewhere (your array structure probably different, as iteration takes place), so you are getting this message, use isset() to or array_key_exists() to validate, depending on the purpose.
Please note isset != array_key_exists
$a = array('key1' => 'test1', 'key2' => null);
isset($a['key2']); // false
array_key_exists('key2', $a); // true
There is another important difference. isset doesn't complain when $a does not exist, while array_key_exists does.
Related
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.
seem to be experiencing something strange. I am loading an Excel file's data into an array. I am handling things like so
foreach ($data->toArray() as $value) {
dd($value);
if(!empty($value)){
foreach ($value as $v) {
dd($v['id']);
$insert[] = [
'id' => $v['id'],
'name' => $v['name']
];
}
}
}
Now the first dd() (laravel output) produces something like so
array:809 [▼
0 => array:20 [▼
"id" => "123"
"name" => "something"
]
...
So I can see there is an array element called id. The second dd, which calls this array element, produces the output 123
The problem comes where I am filling the array with this data. Although I am still using $v['id'] which works for the output, within the array I get the error
Undefined index: id
Why would this be the case when the index is there?
Thanks
Try to add an if to check if the keys really exist in your array. This will avoid situations when the key does not exist and the Undefined index: id error appear.
foreach ($data->toArray() as $value) {
if(!empty($value)){
foreach ($value as $v) {
if (array_key_exists("id",$v) &&
array_key_exists("name",$v)) {
$insert[] = [
'id' => $v['id'],
'name' => $v['name']
];
}
}
}
}
This question is just for fun and out of curiosity.
Edit : My question is different than
How to find the foreach index
Because $key has already a non-numeric value in my case.
Without having a variable outside a foreach that is increment inside the foreach scope, as the usual $i, is there a way to get the index of an item when $key is already named ?
Exemples :
$myNumericIndexArray = ('foo', 'bar', 'go', 'habs');
foreach($myNumericIndexArray as $key => $value){
//Here $key will be 0 -> 1 -> 2 -> 3
}
Now, if I have :
$myNamedIndexArray = ('foo' => 'bar', 'go' => 'habs', 'CSGO_bestTeam' => 'fnatic');
foreach($myNamedIndexArray as $key => $value){
//Here $key will be foo -> go -> CSGO_bestTeam
}
Can I, without having to :
$i=0;
foreach($myNamedIndexArray as $key => $value){
//Here $key will be foo -> go -> CSGO_bestTeam
$i++;
}
access the index of a named array. Something declared in the foreach declaration like in a for or a status of $key ?
Have a good one.
If you really want index array of associative array than try this:
$myNamedIndexArray = ['foo' => 'bar', 'go' => 'habs', 'CSGO_bestTeam' => 'fnatic'];
$keys = array_keys($myNamedIndexArray);
foreach($myNamedIndexArray as $key => $value){
echo array_search($key, $keys);
}
I don't know why you would want to do an array_keys() and array_search() every loop iteration. Just build a reference array and you can still foreach() the original:
$positions = array_flip(array_keys($myNamedIndexArray));
foreach($myNamedIndexArray as $key => $value){
echo "{$key} => {$value} is position {$positions[$key]}\n";
}
Something like this :
<?php
$myNamedIndexArray = array('foo' => 'bar', 'go' => 'habs', 'CSGO_bestTeam' => 'fnatic');
$numericIndexArray = array_keys($myNamedIndexArray);
foreach($numericIndexArray as $key=>$value){
echo $key.'</br>'; //here key will be 0 1 2
echo $value. '</br>';
}
I'd try something like this:
<?php
$myNamedIndexedArray = ['foo' => 'bar', 'go' => 'habs', 'CSGO_bestTeam' => 'fnatic'];
$myNumberIndexedArray = array_keys($myNamedIndexedArray);
foreach($myNumberIndexedArray as $key => $value){
echo $key. " => " . $myNamedIndexedArray[$myNumberIndexedArray[$key]]."<br />";
}
?>
Adn the output will be:
0 => bar
1 => habs
2 => fnatic
I am trying to unset a group of array keys that have the same prefix. I can't seem to get this to work.
foreach ($array as $key => $value) {
unset($array['prefix_' . $key]);
}
How can I get unset to see ['prefix_' . $key] as the actual variable? Thanks
UPDATE: The $array keys will have two keys with the same name. Just one will have the prefix and there are about 5 keys with prefixed keys:
Array {
[name] => name
[prefix_name] => other name
}
I don't want to remove [name] just [prefix_name] from the array.
This works:
$array = array(
'aa' => 'other value aa',
'prefix_aa' => 'value aa',
'bb' => 'other value bb',
'prefix_bb' => 'value bb'
);
$prefix = 'prefix_';
foreach ($array as $key => $value) {
if (substr($key, 0, strlen($prefix)) == $prefix) {
unset($array[$key]);
}
}
If you copy/paste this code at a site like http://writecodeonline.com/php/, you can see for yourself that it works.
You can't use a foreach because it's only a copy of the collection. You'd need to use a for or grab the keys separately and separate your processing from the array you want to manipulate. Something like:
foreach (array_keys($array) as $keyName){
if (strncmp($keyName,'prefix_',7) === 0){
unset($array[$keyName]);
}
}
You're also already iterating over the collection getting every key. Unless you had:
$array = array(
'foo' => 1,
'prefix_foo' => 1
);
(Where every key also has a matching key with "prefix_" in front of it) you'll run in to trouble.
I'm not sure I understand your question, but if you are trying to unset all the keys with a specific prefix, you can iterate through the array and just unset the ones that match the prefix.
Something like:
<?php
foreach ($array as $key => $value) { // loop through keys
if (preg_match('/^prefix_/', $key)) { // if the key stars with 'prefix_'
unset($array[$key]); // unset it
}
}
You're looping over the array keys already, so if you've got
$array = (
'prefix_a' => 'b',
'prefix_c' => 'd'
etc...
)
Then $keys will be prefix_a, prefix_c, etc... What you're doing is generating an entirely NEW key, which'd be prefix_prefix_a, prefix_prefix_c, etc...
Unless you're doing something more complicated, you could just replace the whole loop with
$array = array();
I believe this should work:
foreach ($array as $key => $value) {
unset($array['prefix_' . str_replace('prefix_', '', $key]);
}
I have been working on this a while. I see multi-dimensional arrays in php are not that easy.
Here is my code:
while (list($key,$value) = each ($x))
{
Print "$key => $value\n<br>\n";
}
This works well to display the keys of the main array. what I get is :
visitors => Array
actions => Array
actions-average => Array
time-average => Array
pages-entrance => Array
What I want is the visitors and the value (number of visitors), value of actions, etc.
I want to then save the value in Mysql. Some I will have to convert from a string to and int or date.
I need to list one more level deep. But I cannot see how to do this.
--------------Added -----------
So what I have is an array of arrays. I need to step through each array.
did you try print_r ?
if you need more control over formatting then embedded loops as suggested by #Nick is the best option. Although it would be more natural and safer to use foreach loops rather than while.
foreach($x as $key => $value){
foreach( $value as $key2 => $value2){
print "$key $key2 => $value2\n<br />\n";
}
}
see PHP manual: each , there is a "caution" frame.
EDIT 1
I update sample code above for 2 day array.
It seems your array has more than 2 dimension. Then you should use recursion.
function my_print_r($x,$header="")
{
foreach($x as $key => $value){
if(is_array($value))
my_print_r($value,$header . $key . " " );
else
print "$header $key2 => $value2\n<br />\n";
}
}
Try loops like this code:
$arrA=array("a", "b", "c");
$arrB=array("x", "y", "z");
$x=array("visitors" => $arrA, "actions" => $arrB);
foreach($x as $key => $value)
{
foreach($value as $v)
echo "$key => $v<br>\n";
}
OUTPUT
visitors => a<br>
visitors => b<br>
visitors => c<br>
actions => x<br>
actions => y<br>
actions => z<br
the best way is var_dump($arr);
<?php
var_dump($_SERVER);
?>
with output that includes types, string length, and will iterate over objects as well.
Since you want to iterate over an array, give foreach a try:
foreach ($arr as $el)
{
// ... Work with each element (most useful for non associative arrays, or linear arrays)
}
// or
foreach ($arr as $key => $value)
{
// ... Work with $key and $value pairs (most useful for hashes/associative arrays)
}
/ / . . . here, we take variable $company for nested array and in this variable we put 2 employee id and its called multi-dimensional array and we take $company variable to assign the associative array with keys so we print the output with keys
$company=[
$emp=[1,"neha","employee",12000,30000],
$emp1=[2,"moni","manager",12000],
];
$company=["first" => $emp,"second" => $emp1];
foreach($company as $key => $value)
{
echo "$key ";
foreach($value as $v1){
echo "$v1";
}
}
output :-
employee ID name designation salary bonus
first 1 neha employee 12000 30000
second 2 moni manager 12000