I have a multidimensional array like the following:
Array (
[results] => Array (
[0] => Array (
[object_id] => 13
[id] => 13
[idno] => e00110-o00005-2010-PROG
[display_label] => La Bohème / PUCCINI - 2010
[ca_objects.description] => Libreto de Luigi Illica y Giuseppe Giacosa basado en Escenas de la vida bohemia de Henri Murger Nueva producción – Teatro Colón
[ca_objects.type_id] => Programa de mano
)
//more data here
I'm trying to loop the array and replace "object_id" key for "new_id" using str_replace.
$str="object_id";//The string to search for
$rep="new_id";//The replacement string
foreach ($array as $value) {
foreach ($value as $key2 => $value2) {
foreach ($value2 as $key3 => $value3) {
str_replace($str,$rep,$key3);
echo $key3." : ".$value3."<br>"; //It gets printed with no changes
}
}
}
The above code does not work, can you see what am I doing wrong?.
I tried using strings instead of variables but didn't work either.
Thanks in advance.
...if you really want to use str_replace():
$array['results'] = array_map(function($item){
$keys = implode(',', array_keys($item));
$keys = str_replace('object_id', 'new_id', $keys);
return array_combine(explode(',', $keys), array_values($item));
}, $array['results']);
The other way - create a new array, then iterate over the old array and assign values from it to the new array, while changing the keys you want:
$array['results'] = array_map(function($item){
$item['new_id'] = $item['object_id'];
unset($item['object_id']);
return $item;
}, $array['results']);
(this one will reorder the array, if it matters)
foreach ($array as &$value) {
foreach ($value as $key2 => &$value2) {
$value2[$rep] = $value2[$str];
unset($value2[$str]);
}
}
It's necessary to iterate over the arrays using references so that the modifications affect the original array, not a copy.
#One Trick Pony:
I followed your suggestion and created a new array. It was exactly what I needed and I did it by myself!!. Following code creates the new array. Thank you all so much for helping me!
$display=array();
foreach ($array as $value) {
foreach ($value as $value2) {
$display [] = array (
'Id del objeto' => $value2['object_id'],
'Título' => $value2['display_label'],
'Descripción' => $value2['ca_objects.description'],
);
}
}
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.
I need some help with another PHP problem I am working on. I won't be posting the exact question, as I'd prefer to try and apply the knowledge I get from here to solve my problem.
First:
I have an associative array. I must loop through the array to find the array values which have keys that begin with a specific string and push both the key and value to an output array.
eg:
- Loop through the below array & push all elements which have a key beginning with "edible_" to an output array:
$assoc_array = array(
'edible_fruit' => 'apple',
'animal' => 'cat',
'edible_veg' => 'pumpkin',
'number' => '23',
'city' => 'Cape Town',
'edible_berry' => 'blueberry',
'color' => 'blue'
);
Would this work?
$result = array();
foreach ($assoc_array as $key => $value) {
if (substr($key, 0, 7) == "edible_") {
array_push($result, $value);
}
}
print_r($result);
Second:
How would I remove "edible_" from the output array's keys? With this second bit I have no idea where to even begin!
Third:
I've managed to figure out the above with all your help, thank you! Now I just need to find out how I would print each element on a new line with a date & timestamp at the end of each line? I've got this (doesn't seem to be working):
while (list($key, $value) = each($output)) {
print_r("$key => $value" . date("y/m/d G.i:s", time()) . "<br>");
}
First of your code will work.
To remove edible_ from the key you could use explode() -
$keyParts = explode('_', $key);
$newKey = $keyParts[1];
You will have to add the new keys to the array, which you're not doing now.
foreach ($assoc_array as $key => $value) {
if (substr($key, 0, 7) == "edible_") {
$keyParts = explode('_', $key);
$newKey = $keyParts[1];
$result[$newKey] = $value;
}
}
This would be my approach:
foreach($assoc_array as $key => $value) {
if(preg_match("/^edible_/",$key)) {
$result[preg_replace("/^edible_/","",$key)] = $value;
}
}
use preg_match to check if the key starts with what you are looking for and use preg_replace to remove the string from the beginning (^) of the key :)
Input ($assoc_array):
Array
(
[edible_fruit] => apple
[animal] => cat
[edible_veg] => pumpkin
[number] => 23
[city] => Cape Town
[edible_berry] => blueberry
[color] => blue
)
Output ($result):
Array
(
[fruit] => apple
[veg] => pumpkin
[berry] => blueberry
)
First: yes, that would work, however I would rewrite it a bit:
foreach ($assoc_array as $key => $value) {
if (strpos($key, 'edible_') === 0) {
$result[] = $value;
}
}
Regarding Second: You are asking how to remove the key from the output array. However you did not even push the key into the output array, you only pushed the value. If you'd like to also push the key, you should do it like this:
$result[$key] = $value;
But since you haven't done that, there's no need to remove the key.
If you however meant removing the edible_ part of the key from the $assoc_array, you'd just need to add a line to the loop and pass the key by reference by adding a &:
foreach ($assoc_array as &$key => $value) {
if (strpos($key, 'edible_') === 0) {
$key = str_replace('edible_', '', $key)
$result[] = $value;
}
}
Edit: As OP told me in comments, she wants to push the key without the edible part. So just do it like this:
foreach ($assoc_array as $key => $value) {
if (strpos($key, 'edible_') === 0) {
$key = str_replace('edible_', '', $key)
$result[$key] = $value;
}
}
This should work for you:
First I remove all elements, which doesn't have edible_ at the start of the key with array_diff_ukey(). After this I simply array_combine() the elements with they keys, where I remove the prefix with array_map() and substr().
<?php
$assoc_array = array('edible_fruit'=>'apple', 'animal'=>'cat', 'edible_veg'=>'pumpkin', 'number'=>'23', 'city'=>'Cape Town', 'edible_berry'=>'blueberry', 'color'=>'blue');
//remove elemnts
$result = array_diff_ukey($assoc_array, ["edible_" => ""], function($k1, $k2){
return substr($k1, 0, 7) == $k2;
});
//change keys
$result = array_combine(
array_map(function($v){
return substr($v, 7);
}, array_keys($result)),
$result);
print_r($result);
?>
output:
Array ( [fruit] => apple [veg] => pumpkin [berry] => blueberry )
You can loop through the array and search if the key has the string that you can eliminate and make your $newArray
<?php
$assoc_array = array('edible_fruit'=>'apple', 'animal'=>'cat', 'edible_veg'=>'pumpkin', 'number'=>'23', 'city'=>'Cape Town', 'edible_berry'=>'blueberry', 'color'=>'blue');
$search = 'edible_';
$newArray = array();
#First and Second Step
foreach($assoc_array as $key => $value) {
if(strpos($key, "edible_") === 0) {
$newArray[substr($key, 7)] = $value;
}
}
print_r($newArray);
echo "<br>\n";
#Third Step
foreach($newArray as $key => $value) {
echo "$key => $value " . date("y/m/d G.i:s", time()) . "<br>\n";
}
Output:
#First and Second Step
Array ( [fruit] => apple [veg] => pumpkin [berry] => blueberry )
#Third Step
fruit => apple 15/04/10 3.02:16
veg => pumpkin 15/04/10 3.02:16
berry => blueberry 15/04/10 3.02:16
Consider the following array:
$array[23] = array(
[0] => 'FOO'
[1] => 'BAR'
[2] => 'BAZ'
);
Whenever I want to work with the inner array, I do something like this:
foreach ($array as $key => $values) {
foreach ($values as $value) {
echo $value;
}
}
The outer foreach-loop is there to split the $key and $value-pairs of $array. This works fine for arrays with many keys ([23], [24], ...)but seems redundant if you know beforehand that $array only has one key (23 in this case). In a case as such, isn't there a better way to split the key from the values? Something like
split($array into $key => $values)
foreach ($values as $value) {
echo $value;
}
I hope I made myself clear.
reset returns the first element of you array and key returns its key:
$your_inner_arr = reset($array);
$your_key = key($array);
Yea, just get rid of your first foreach and define the array you're using with the known $key of your outter array.
foreach ($array[23] as $key =>$val):
//do whatever you want in here
endforeach;
If an array has only one element, you can get it with reset:
$ar = array(23 => array('foo', 'bar'));
$firstElement = reset($ar);
A very succinct approach would be
foreach(array_shift($array) as $item) {
echo $item;
}
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