Array map, flatten and merge PHP - php

Array
(
[0] => Array
(
[id] => 1
[name] => Sister
[biological] => true
[sibling] => Array
)
[1] => Array
(
[id] => 2
[name] => Brother
[biological] => true
[sibling] => Array
(
[id] => 1
[name] => Brother1
[biological] => true
[sibling] => Array
)
(
[id] => 2
[name] => Sister1
[biological] => true
[sibling] => Array
)
)
)
I have here a multidimensional array
I am attempting to retrieve value from Brother under siblings array.
Ideally the end result should be like this:
Sisblings Array
(
"Sister"
"Brother"
"Brother1"
"Sister1"
)
I have tried foreach to catch the arrays but instead of returning all the siblings as intended, its overlapping the array under brothers siblings.
foreach ($tree['siblings'] as $i => $sibling) {
$tree['siblings'][$i]->siblings = $this->getRelationshipData($sibling->id, $region_id, $sibling_ids, $member->getKey());
foreach ($sibling->siblings ['sibligns'] as $j => $p) {
$tree['siblings'][$i]->siblings[$j]->relationship = $p->relationship;
}
return $tree;

You could also use a array_walk_recursive() to retrieve the data you need.
array_walk_recursive($array, function($val,$key) use(&$result){
if($key === "name") $result[] = $val;
});
The end result is the $result array.

Related

Sequence issue with nested foreach loop php

I have two array. array one and array two. I want to merge these array into single array with key. My output result is valid but sequence is not correct.
Array one
Array
(
[0] => test-685f1e7bc357187e449479d627100102
[1] => test-685f1e7bc357187e449479d627d29390
)
Array two
Array
(
[0] => DF955298-A664-4FA7-9586-FCD4CF977777
[1] => DF955298-A664-4FA7-9586-FCD4CF988888
)
Expected Result
Array
(
[0] => Array
(
[key] => test-685f1e7bc357187e449479d627100102
[uuid] => DF955298-A664-4FA7-9586-FCD4CF977777
)
[1] => Array
(
[key] => test-685f1e7bc357187e449479d627d29390
[uuid] => DF955298-A664-4FA7-9586-FCD4CF988888
)
)
My code is for that result is mentioned below:
$record = array();
foreach ($keys_array as $key => $all_key) {
foreach ($uuid_array as $uuid_key => $all_uuid) {
$record[$key]['key'] = $all_key;
$record[$uuid_key]['uuid'] = $all_uuid;
}
}
My output sequence is not valid. Where is the problem
Array
(
[0] => Array
(
[key] => test-685f1e7bc357187e449479d627100102
[uuid] => DF955298-A664-4FA7-9586-FCD4CF977777
)
[1] => Array
(
[uuid] => test-685f1e7bc357187e449479d627d29390
[key] => DF955298-A664-4FA7-9586-FCD4CF988888
)
)
Simple solution:
$record = array();
foreach ($keys_array as $key => $all_key) {
$record[] = [
'key' => $all_key,
// get value under the same key from `$uuid_array`
'uuid' => $uuid_array[$key],
];
}

How to concatenate arrays element recursively [duplicate]

This question already has answers here:
Joining similar data from two indexed arrays
(2 answers)
Closed 5 months ago.
I'm working on a project and I'm stacked since 2 days, this is my problem: I have two arrays and want to retrieve the second item in each object in Array_2 and concatenate it to the content of each object in first Array_1 in PHP.
Array_1
[[1453274700000,24011],[1453275000000,24222],[1453275300000,24284],[1453275600000,24331],...]
Array_2
[[1453274700000,51951],[1453275000000,52093],[1453275300000,52251],[1453275600000,52288],...]
Wanted_array
[[1453274700000,24011,51951],[1453275000000,24222,52093],[1453275300000,24284,52251],[1453275600000,24331,52288]...]
A functional solution:
$result = array_map(function (array $a1, array $a2) {
return array_merge($a1, [$a2[1]]);
}, $array_1, $array_2);
This assumes that all items are in order and only need to be merged by their order, not by their first value.
If you want $item[0] to define what "group" each value belongs to, you can iterate through the first array and save $item[0] as the key and $item[1] as the value. Do the same for the second array. Now iterate through the saved array for array1, and check if the saved array for array2 contains the same keys. Do the same for array2 (in case it has key that array1 doesn't have), and save it all to a new array:
<?php
$arr1 = array(
array('1453274700000',24011),
array('1453275000000',24222),
array('1453276000000',24222), // inexistent in $arr2
);
$arr2 = array(
array('1453275000000',52093),
array('1453274700000',51951),
array('1453273000000',24222), // inexistent in $arr1
);
$arr1dictionary = [];
$arr2dictionary = [];
$result = [];
foreach ($arr1 as $collection) {
$arr1dictionary[$collection[0]] = $collection[1];
}
foreach ($arr2 as $collection) {
$arr2dictionary[$collection[0]] = $collection[1];
}
foreach ($arr1dictionary as $key => $value) {
if (isset($arr2dictionary[$key])) {
$result[$key] = [$key, $value, $arr2dictionary[$key]];
} else {
$result[$key] = [$key, $value, null];
}
}
foreach ($arr2dictionary as $key => $value) {
if (isset($result[$key])) {
continue;
}
$result[$key] = [$key, null, $value];
}
$result = array_values($result);
print_r($result);
Output:
Array
(
[0] => Array
(
[0] => 1453274700000
[1] => 24011
[2] => 51951
)
[1] => Array
(
[0] => 1453275000000
[1] => 24222
[2] => 52093
)
[2] => Array
(
[0] => 1453276000000
[1] => 24222
[2] => (null, the value only exists in $arr1)
)
[3] => Array
(
[0] => 1453273000000
[1] => (null, the value only exists in $arr2)
[2] => 24222
)
)
DEMO
Use array_walk and add second item from $array2 if it exists.
$array1 = array(
array(1453274700000,24011),
array(1453275000000,24222),
array(1453275300000,24284),
array(1453275600000,24331)
);
$array2 = array(
array(1453274700000,51951),
array(1453275000000,52093),
array(1453275300000,52251),
array(1453275600000,52288),
);
array_walk($array1, function(&$item, $key) use ($array2){
if(isset($array2[$key][1])){
$item[] = $array2[$key][1];
}
});
print_r($array1);
Output
Array
(
[0] => Array
(
[0] => 1453274700000
[1] => 24011
[2] => 51951
)
[1] => Array
(
[0] => 1453275000000
[1] => 24222
[2] => 52093
)
[2] => Array
(
[0] => 1453275300000
[1] => 24284
[2] => 52251
)
[3] => Array
(
[0] => 1453275600000
[1] => 24331
[2] => 52288
)
)
EDIT
As #h2ooooooo pointed out that there could be possibility that array items are in random order. If array items can be in random order and they are matched with first index value, use this (works with PHP >= 5.5.0):
$array1 = array(
array(1453274700000,24011),
array(1453275000000,24222),
array(1453275300000,24284),
array(1453275600000,24331),
array(1453276000000,24222) // no match in $array2
);
$array2 = array(
array(1453275000000,52093),
array(1453274700000,51951),
array(1453275300000,52251),
array(1453275600000,52288),
);
array_walk($array1, function(&$item, $key) use ($array2){
// Find match in $array2
$array2_key = array_search($item[0], array_column($array2, 0));
// If match found
if($array2_key !== false && isset($array2[$array2_key][1])){
$item[] = $array2[$array2_key][1];
}
// No match
else{
$item[] = null;
}
});
print_r($array1);
OUTPUT
Array
(
[0] => Array
(
[0] => 1453274700000
[1] => 24011
[2] => 51951
)
[1] => Array
(
[0] => 1453275000000
[1] => 24222
[2] => 52093
)
[2] => Array
(
[0] => 1453275300000
[1] => 24284
[2] => 52251
)
[3] => Array
(
[0] => 1453275600000
[1] => 24331
[2] => 52288
)
[4] => Array
(
[0] => 1453276000000
[1] => 24222
[2] =>
)
)

How to combine inner array values in one multidimensional array?

Hi I have one multidimensional array, I retrieved the data using mysql PDO and formatted it this way
array('id'=>$row['empname'],'data'=>array(array($row['salestat'],$row['salecount'])))
Array
(
[0] => Array
(
[id] => 'employee1'
[data] => Array
(
0 => 'Sold'
1 => 1
)
)
[1] => Array
(
[id] => 'employee2'
[data] => Array
(
0 => 'On Process'
1 => 4
)
)
[2] => Array
(
[id] => 'employee2'
[data] => Array
(
0 => 'Sold'
1 => 2
)
)
)
I am trying to make my output like this, trying to format this so I can use it for drilldown series in highcharts, thank you
Array
(
[0] => Array
(
[id] => 'employee1'
[data] => Array
(
0 => 'Sold'
1 => 1
)
)
[1] => Array
(
[id] => 'employee2'
[data] => Array
[0]
(
0 => 'On Process'
1 => 4
)
[1]
(
0 => 'Sold'
1 => 2
)
)
)
Firstly, you can not use a field inside an array twice with the same key like salescount or salestat. But you can do something like this.
function wrapSameId( $employeeArray ) {
//create the new array.
$newEmployeeArray = array();
//loop the old array.
foreach ($employeeArray as $key => $value) {
$exists = 0;
$i=0;
$id = $value['id'];
$data = $value['data'];
//see if you can find the current id inside the newly created array if you do, only push the new data in.
foreach ($newEmployeeArray as $key2 => $value2) {
if( $id == $value2['id'] ) { $newEmployeeArray[$key2]['data'][] = $data;$exists = 1;var_dump($value2['data']); }
$i++;
}
//if we didnt find the id inside the newly created array, we push the id and the new data inside it now.
if( $exists == 0 ){
$newEmployeeArray[$i]['id'] = $id;
$newEmployeeArray[$i]['data'][] = $data;
}
}
return $newEmployeeArray;
}
This function should return a new Array but if in the old array there were multiple arrays with the same id, in this one we should have:
Array
(
[0] => Array
(
[id] => employee1
[data] => Array
(
[0] => Array
(
[salescount] => 4
[salesstat] => Sold
)
)
)
[1] => Array
(
[id] => employee2
[data] => Array
(
[0] => Array
(
[salescount] => 2
[salesstat] => In Progress
)
[1] => Array
(
[salescount] => 5
[salesstat] => Sold
)
)
)
)
You can use it like this:
$employees = wrapSameId( $PDOArray );
where $PDOArray is your initial Array. Hope this is what you were looking for.
Why not index your output array by id?
Loop over your initial array and add the salecount, salestat pair to an employee's data array.
$outputArray = array();
//Loop over each entry pulled from you database...
foreach ($employeeArray as $employeeInfo)
{
//If no index for the current employee exists, create an empty array
//The only reason I'm including this is because I'm not sure how array_merge handles nulls -- just to be safe
if (!$outputArray[$employeeInfo['id']])
{
$outputArray[$employeeInfo['id']] = array();
}
//Merge the existing array for that employee with the new data for the same employee
$outputArray[$employeeInfo['id']] = array_merge($outputArray[$employeeInfo['id']], $employeeInfo['data']);
}
print_r($outputArray);
It's easier to visualize the output...
Array
(
[employee1] => Array
(
0 => 1
1 => 'Sold'
)
[employee2] => Array
(
0 => 4
1 => 'On Process'
2 => 2
3 => 'Sold'
)
)
If you're not satisfied with your output being indexed by id, loop over it again and format it as you want.
$otherOutputArray = array();
foreach ($outputArray as $key => $value)
{
$otherOutputArray[] = array('id' => $key, 'data' => $value);
}
That gives you exactly what you want.

Merge 2 arrays of objects in PHP [duplicate]

This question already has answers here:
Merging and group two arrays containing objects based on one identifying column value
(4 answers)
Closed last month.
How do you merge array1 and 2?
array1
Array
(
[0] => stdClass Object
(
[name] => bob
[id] => 84569354306
[contacts] => Array
(
[0] => none
)
)
[1] => stdClass Object
(
[name] => jill
[id] => 456745742
[contacts] => Array
(
[0] => none
)
)
)
array2
Array
(
[0] => stdClass Object
(
[name] => bob
[id] => 84569354306
[pid] => 1
[lang] => eng;
[location] =>
)
[1] => stdClass Object
(
[name] => jill
[id] => 456745742
[pid] => 2
[lang] => eng;
[location] =>
)
)
Result array:
Array
(
[0] => stdClass Object
(
[name] => bob
[id] => 84569354306
[pid] => 1
[lang] => eng;
[location] =>
[contacts] => Array
(
[0] => none
)
)
[1] => stdClass Object
(
[name] => jill
[id] => 456745742
[pid] => 2
[lang] => eng;
[location] =>
[contacts] => Array
(
[0] => none
)
)
)
I've tried an array_merge() which seems to add objects next to each other in the array rather than merging the objects.
I'm pretty sure this question is similar to what I need, but I'm having difficulty with the simple foreach loop.
You can cast the two objects to array and then re-cast back to an object. The general syntax is:
$merged = (object)array_merge_recursive((array)$firstObj, (array)$secondObj);
^
| note the recursive in your case
Also, if you are using objects like that maybe you should simply stick to array. It has very little to no sense to do something like that with objects
With multiple items
If you have multiple items you simply need to wrap up my script inside a loop:
function myCustomMerge($array1, $array2) {
assert('count($array1) == count($array2)');
$result = array();
foreach($array1 as $k=>$v) {
$item = array_merge_recursive((array)$array1[$k], (array)$array2[$k]);
$result[]=$item; // use (object)$item if you need objects
}
return $result;
}
Solution without casting
If you prefer not to cast back and forth between array and object you can use get_object_vars():
$obj2props = get_object_vars($obj2);
foreach ($obj2props as $prop => $value) {
$obj1->$prop = $value;
}
return $obj;
Another way of doing it:
function merge_values(){
$list = func_get_args();
while( count( $list ) > 1 ){
$array1 = array_shift( $list );
$array2 = array_shift( $list );
$merged_array = $array1;
foreach( $array2 as $key => $value ){
$merged_array[$key] = array_merge( (array)$value, (array)$merged_array[$key] );
if( is_object( $value ) || is_object( $array1[$key] ) ){
$merged_array[$key] = (object)$merged_array[$key];
}
}
array_unshift( $list, $merged_array );
}
return current( $list );
}
$merged = merge_values( $array1, $array2 );

php multidemensional array to simple array

I need this multidimensional array converted to a simple array.
Array
(
[0] => Array
(
[id_zub] => 1
[name] => Backen
)
[1] => Array
(
[id_zub] => 2
[name] => Kochen
)
)
A simple array:
array(
[id_zub] => 1
[name] => Backen
[id_zub] => 2
[name] => Kochen
)
function array_flattern($array){
foreach($array as $key=> $value){
if(is_array($value)){
$this->array_flattern($value);
}
else{
$this->result[$key] = $value;
}
}
}
The function gives me this result:
Array
(
[id_zub] => 2
[name] => Kochen
)
your function works as intended, Your getting a "key clash" and the latter key's value is the one used. You would have yo have a suffix on the key if you wanted it in one dimension
eg
Array ( [id_zub_2] => Kochen )

Categories