I have a really basic problem. I want to iterate through a multidimensional-array. Suppose I want to add an if statement to check values without breaking the foreach loop... my purpose is to get an array of specific values
$foo = [
'one'=> [
'id'=>1,
'name'=>'32dsfd23'
],
'two' => [
'id'=>1,
'name'=>'322e3'
],
];
function new_func($arr){
$data=[];
foreach($arr as $val) {
foreach($val as $key =>$foofoo) {
if(array_key_exists('id',$val)){
$data['new_arr']=$foofoo;
}
}
}
return $data;
}
echo "<pre>";
print_r(new_func($foo));
echo "</pre>";
The result is :
Array
(
[new_arr] => 322e3
)
And I want to get something like this :
Array
(
[new_arr]
[0]=> 32dsfd23,
[1]=> 322e3,
)
You need to push the new elements in the array. Now you overwrite them.
$foo = [
'one'=> [
'id'=>1,
'name'=>'32dsfd23'
],
'two' => [
'id'=>1,
'name'=>'322e3'
],
];
function new_func($arr){
$data=[];
foreach($arr as $val) {
foreach($val as $key =>$foofoo) {
if(array_key_exists('id',$val)) {
$data['new_arr'][] = $foofoo;
}
}
}
return $data;
}
echo "<pre>";
print_r(new_func($foo));
echo "</pre>";
When you do
$data['new_arr']=$foofoo;
you're overwriting the value in your $data['new_arr'].
You need to change that to $data['new_arr'][]=$foofoo; which will insert the value in that array.
Related
I want to combine two different multi-dimensional arrays, with one providing the correct structure (keys) and the other one the data to fill it (values).
Notice that I can't control how the arrays are formed, the structure might vary in different situations.
$structure = [
"a",
"b" => [
"b1",
"b2" => [
"b21",
"b22"
]
]
];
$data = [A, B1, B21, B22];
Expected result:
$array = [
"a" => "A",
"b" => [
"b1" => "B1",
"b2" => [
"b21" => "B21",
"b22" => "B22"
]
]
];
You can use the following code, however it will only work if number of elements in $data is same or more than $structure.
$filled = 0;
array_walk_recursive ($structure, function (&$val) use (&$filled, $data) {
$val = array( $val => $data[ $filled ] );
$filled++;
});
print_r( $structure );
Here is a working demo
You can try by a recursive way. Write a recursive method which takes an array as first argument to alter and the data set as its second argument. This method itself call when any array element is another array, else it alters the key and value with the help of data set.
$structure = [
"a",
"b" => [
"b1",
"b2" => [
"b21",
"b22"
]
]
];
$data = ['A', 'B1', 'B21', 'B22'];
function alterKey(&$arr, $data) {
foreach ($arr as $key => $val) {
if (!is_array($val)) {
$data_key = array_search(strtoupper($val), $data);
$arr[$val] = $data[$data_key];
unset($arr[$key]);
} else {
$arr[$key] = alterKey($val, $data);
}
}
ksort($arr);
return $arr;
}
alterKey($structure, $data);
echo '<pre>', print_r($structure);
Working demo.
This should work.
$structure = [
"a",
"b" => [
"b1",
"b2" => [
"b21",
"b22"
]
]
];
$new_structure = array();
foreach($structure as $key =>$value)
{
if(!is_array($value))
{
$new_structure[$value]= $value;
}else{
foreach($value as $k =>$v)
{
if(!is_array($v))
{
$new_structure[$key][$v]=$v;
}else
{
foreach($v as $kk => $vv)
{
$new_structure[$k][$vv]=$vv;
}
}
}
}
}
print_r($new_structure);exit;
Use
$array=array_merge($structure,$data);
for more information follow this link
how to join two multidimensional arrays in php
I have a json data. Now I want to reform it. In my json data there is a property like person_on_zone I want to make a property named person_info and store them which person under this area.
Here is my data any code. Thanks in advance
My json data
$val = [
{
'city':'xx',
'zone':'yy',
'person_on_zone':'p1'
},
{
'city':'xx',
'zone':'yy',
'person_on_zone':'p2'
},
{
'city':'xx',
'zone':'yy',
'person_on_zone':'p3'
},
{
'city':'xx',
'zone':'ww',
'person_on_zone':'p1'
},
]
My expectation is
[
{
'city':'xx',
'zone':'yy',
'person_info':{
'person_on_zone':'p1',
'person_on_zone':'p2',
'person_on_zone':'p3',
}
},
{
'city':'xx',
'zone':'ww',
'person_info':{
'person_on_zone':'p1'
}
},
]
Here I tried
foreach ($val as $v) {
$new_array['city'] = $v['city'];
$new_array['zone'] = $v['zone'];
foreach ($val as $v2) {
$new_array['person_info'] = $v['person_on_zone'];
}
}
json_encode($new_array);
Try this, use $map to store key city-zone, then transform to array to get the result
<?php
$val = [
[
'city' => 'xx',
'zone' => 'yy',
'person_on_zone' => 'p1'
],
[
'city' => 'xx',
'zone' => 'yy',
'person_on_zone' => 'p2'
],
[
'city' => 'xx',
'zone' => 'yy',
'person_on_zone' => 'p3'
],
[
'city' => 'xx',
'zone' => 'ww',
'person_on_zone' => 'p1'
]
];
$map = [];
foreach ($val as $v) {
$key = $v['city'] . $v['zone'];
if (!isset($map[$key])) {
$map[$key] = [
'city' => $v['city'],
'zone' => $v['zone'],
'person_info' => []
];
}
$map[$key]['person_info'][] = $v['person_on_zone'];
}
print_r(array_values($map));
Correct Code
foreach ($val as $v){
$new_array['city'] = $v['city'];
$new_array['zone'] = $v['zone'];
foreach ($val as $v2){
$new_array['person_info'] = $v2['person_on_zone'];
}
}
json_encode($new_array);
try this:
first decode json array then use foreach loop with key
$val = json_decode($val);
foreach ($val as $v){
$new_array['city'] = $v->city;
$new_array['zone'] = $v->zone;
foreach ($val as $key=>$v2){
$new_array[$key]['person_info'] = $v->person_on_zone;
}
}
print_r($new_array);
I think you make a mistake around composing the json. I tried with your code and i found following is the correct way to do.. Remember single quote(') is not valid in json string that is being used to define key value pair in php
// I think your code has json string and i convert it into array of objects(stdClass)
// and if your code has array then keep you code intact but need to change the notation of
// objects to associative array.
// first thing first decode json string
$values = json_decode('[
{ "city":"xx",
"zone":"yy",
"person_on_zone":"p1"
},
{
"city":"xx",
"zone":"yy",
"person_on_zone":"p2"
},
{
"city":"xx",
"zone":"yy",
"person_on_zone":"p3"
},
{
"city":"xx",
"zone":"ww",
"person_on_zone":"p1"
}]');
// Now declare new values as array
$new_values = [];
// walk through each object
foreach ($values as $v){
// $v becomes an object of stdClass here
// $data is a temporary array
$data['city'] = $v->city;
$data['zone'] = $v->zone;
$data['person_info'] = [];
foreach ($values as $v2){
if(!in_array($data['person_info'],['person_on_zone' => $v2->person_on_zone]))
{
// compare if zones are same or not
if($v->zone == $v2->zone)
{
// push to the array instead of assiging
array_push($data['person_info'], ['person_on_zone' => $v2->person_on_zone]);
}
}
}
// make array unique
$data['person_info'] = array_map("unserialize", array_unique(array_map("serialize", $data['person_info'])));
array_push($new_values, $data);
}
// make array unique in mutidimensional array
$new_values = array_map("unserialize", array_unique(array_map("serialize", $new_values)));
echo '<pre>';
print_r($new_values);
echo '</pre>';
One simple foreach would do,
$result = [];
foreach ($arr as $key => $value) {
//created unique combination of city and zone as key
$result[$value['city'] . $value['zone']]['city'] = $value['city'];
$result[$value['city'] . $value['zone']]['zone'] = $value['zone'];
$result[$value['city'] . $value['zone']]['person_info'][] = ['person_on_zone' => $value['person_on_zone']];
}
echo json_encode(array_values($result));die;
array_values — Return all the values of an array
Working demo.
How can I obtain a key in a array just by knowing it's value? For example, here is an array:
$array = Array("Item1" => array("Number" => "One", "Letter" => "A"));
Just by knowing "One" or "A", how can I get the main key name, Item1?
I've looked into array_key_value and in_array but I do not think that those functions are helpful for my kind of array.
Since it is a 2d array, you will want to search the inner array for the value so you would have to make your own function to do this. Something like this:
function findInArray($array, $lookup){
//loop over the outer array getting each key and value.
foreach($array as $key=>$value){
//if we found our lookup value in the inner array
if(in_array($lookup, $value)){
//return the original key
return $key;
}
}
//else, return null because not found
return null;
}
$array = Array("Item1" => array("Number" => "One", "Letter" => "A"));
var_dump(findInArray($array, 'One')); //outputs string(5) "Item1"
var_dump(findInArray($array, 'Two')); //outputs null
Demo: https://3v4l.org/oRjHK
This function may help you
function key_of_value($array, $value){
foreach($array as $key=>$val){
if(in_array($value, $val)){
return $key;
}
}
return null;
}
echo key_of_value(['Item1'=>['One','Two','Three','Hello',2,6]],'A');
There is no way around iterating through your data. This might be a little more elegant than two foreach loops:
<?php
$match = null;
$needle = 'Two';
$haystack = [
'Item1' => [
'Number' => 'One',
'Letter' => 'A'
],
'Item2' => [
'Number' => 'Two',
'Letter' => 'B'
],
'Item3' => [
'Number' => 'Three',
'Letter' => 'C'
],
];
array_walk($haystack, function($entry, $key) use ($needle, &$match) {
if(in_array($needle, $entry)) {
$match = $key;
}
});
var_dump($match);
The output obviously is:
string(5) "Item2"
You can use array_walk_recursive to iterate on array values recursive. I write a function that return main key of searched value in nested arrays.
<?php
$array = array("Item1" => array("Number" => "One", "Letter" => "A", 'other' => array('Number' => "Two")));
echo find_main_key($array, 'One'); //Output: "Item1"
echo find_main_key($array, 'A'); //Output: "Item1"
echo find_main_key($array, 'Two'); //Output: "Item1"
var_dump(find_main_key($array, 'nothing')); // NULL
function find_main_key($array, $value) {
$finded_key = NULL;
foreach($array as $this_main_key => $array_item) {
if(!$finded_key) {
array_walk_recursive($array_item, function($inner_item, $inner_key) use ($value, $this_main_key, &$finded_key){
if($inner_item === $value) {
$finded_key = $this_main_key;
return;
}
});
}
}
return $finded_key;
}
This is how I would do it:
foreach($array as $key => $value) {
if(in_array('One', $value)) echo $key;
}
i had a array to each its item was object , i've converted that array with following code :
json_decode(json_encode($array), true)
that the result of code was a array like this :
[
'1'=>[
'slug'=>'a'
'title'=>'foo'
],
'2'=>[
'slug'=>'b'
'title'=>'bar'
],
'3'=>[
'slug'=>'c'
'title'=>'foo'
],
]
now i want to covert this array to somethings like this
[
'a'=>'foom',
'b'=>'bar',
'c'=>'foo',
]
how can i do it ??
Use foreach and array_combine()
foreach ($your_array as $key => $value) {
// get all the keys in $slug array
$slug[] = $value['slug'];
// get all the values in $title array
$title[] = $value['title'];
}
// finally combine and get your required array
$required_array = array_combine($slug, $title);
I think it can also be acheived with -
$requiredArray = array_combine(
array_column($your_array, 'slug'),
array_column($your_array, 'title')
);
You have to iterate over the initial array and create the new one like this:
$array = [
'1'=>[
'slug'=>'a'
'title'=>'foo'
],
'2'=>[
'slug'=>'b'
'title'=>'bar'
],
'3'=>[
'slug'=>'c'
'title'=>'foo'
],
];
$result = [];
foreach($array as $elem){
$index = $elem["slug"];
$value= $elem["title"];
$result[$index] = $value;
}
foreach($array as $elem){
$result[$elem["slug"]] = $elem["title"];
}
How to convert this array:
$array = [
"order" => [
"items" => [
"6" => [
"ndc" => "This value should not be blank."
],
"7" => [
"ndc" => "This value should not be blank."
]
]
]
];
to
$array = [
"order[items][6][ndc]" => "This value should not be blank.",
"order[items][7][ndc]" => "This value should not be blank.",
];
First array may have unlimited number of nested levels. So nested foreach is not an option.
I spent a lot of time searching for the solution and got nothing. Can, please, someone help or guide me?
Something like this should do the job :
$newArr = [];
function reduce_multi_arr($array, &$newArr, $keys = '') {
if (!is_array($array)) {
$newArr[$keys] = $array;
} else {
foreach ($array as $key => $val) {
if ($keys === '') $nextKey = $key; // first key
else $nextKey = '[' . $key . ']'; // next [keys]
reduce_multi_arr($val, $newArr, $keys . $nextKey);
}
}
}
reduce_multi_arr($array, $newArr);
print_r($newArr);
Output :
Array
(
[order[items][6][ndc]] => 'This value should not be blank.'
[order[items][7][ndc]] => 'This value should not be blank.'
)