How to remove some keys from an array inside another array in PHP?
I have this structure:
array (
0 =>
array (
'num' => '123',
'nome' => 'test 001'
'pontos' => 68,
'data_status' => '03/09/2021 10:05',
'uuid_status' => '69450ea451ae11ea85ca309c23d3a0ed'
),
1 =>
array (
'num' => '345',
'nome' => 'test 002'
'pontos' => 120,
'data_status' => '27/08/2021 15:46',
'uuid_status' => '3cbf4fd15d5411ea86956eef5d66cb13',
),
)
and need to return something like this:
array (
0 =>
array (
'num' => '123',
'nome' => 'test 001'
'pontos' => 68
),
1 =>
array (
'num' => '345',
'nome' => 'test 002'
'pontos' => 120
)
)
I've seen some answers but they seem to be outdated, also i'm using Laravel, so it would help if someone point me out something from the framework and its equivalent in pure PHP
A simple foreach loop is a good starting point, note this will remove items from the original array, by using the reference & to the array rather than a normal simple copy. On the $val in the foreach ( $input as &$val){
$input = [
[
'num' => '123',
'nome' => 'test 001',
'pontos' => 68,
'data_status' => '03/09/2021 10:05',
'uuid_status' => '69450ea451ae11ea85ca309c23d3a0ed'
],[
'num' => '345',
'nome' => 'test 002',
'pontos' => 120,
'data_status' => '27/08/2021 15:46',
'uuid_status' => '3cbf4fd15d5411ea86956eef5d66cb13'
]
];
$remove = ['data_status','uuid_status'];
foreach ( $input as &$val){
foreach ($val as $k => $v) {
if ( in_array($k,$remove) ) {
unset( $val[$k]);
}
}
}
print_r($input);
RESULT
Array
(
[0] => Array
(
[num] => 123
[nome] => test 001
[pontos] => 68
)
[1] => Array
(
[num] => 345
[nome] => test 002
[pontos] => 120
)
)
Probably not the most concise, but it gets the job done:
$bad_keys = array('data_status', 'uuid_status');
$array = array (
0 =>
array (
'num' => '123',
'nome' => 'test 001',
'pontos' => 68,
'data_status' => '03/09/2021 10:05',
'uuid_status' => '69450ea451ae11ea85ca309c23d3a0ed',
),
1 =>
array (
'num' => '345',
'nome' => 'test 002',
'pontos' => 120,
'data_status' => '27/08/2021 15:46',
'uuid_status' => '3cbf4fd15d5411ea86956eef5d66cb13',
),
);
function traverse_array($array, $bad_keys) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = traverse_array($value, $bad_keys);
} else {
foreach ($bad_keys as $remove_me) {
if ($key == $remove_me) {
unset($array[$key]);
}
}
}
}
return $array;
}
print_r(traverse_array($array, $bad_keys));
Related
I have this kind of array , based on Page ID like : 32,143.
I want to search if array key position have both value in it , then ignore prepend and append value and consider ONLY both value.
And if the array has NO both value and multiple prepend and append value, then it will consider based on priority key.
$sort_result = Array
(
[32] => Array
(
[0] => Array
(
[page] => 32
[position] => append
[priority] => 1
)
[1] => Array
(
[page] => 32
[position] => append
[priority] => 2
)
[2] => Array
(
[page] => 32
[position] => prepend
[priority] => 3
)
[3] => Array
(
[page] => 32
[position] => both
[priority] => 3
)
[4] => Array
(
[page] => 32
[position] => prepend
[priority] => 4
)
)
[143] => Array
(
[0] => Array
(
[page] => 143
[position] => prepend
[priority] => 19
)
[1] => Array
(
[page] => 143
[position] => prepend
[priority] => 18
)
[2] => Array
(
[page] => 143
[position] => append
[priority] => 18
)
)
)
I tried the following code , but not working :
<?php
foreach ( $modify_array as $key => $value ) {
foreach( $value as $k1 => $v1) {
if ( array_search( "both", $v1 ) ) {
$final_array[$key][$k1] = $v1;
} else{
if ( array_search( "prepend", $v1 ) ) {
$final_array[$key][$k1] = $v1;
}
if ( array_search( "append", $v1 ) ) {
$final_array[$key][$k1] = $v1;
}
}
break;
}
}
I am expecting output like this :
Array
(
[32] => Array
(
[3] => Array
(
[page] => 32
[position] => both
[priority] => 3
)
)
[143] => Array
(
[1] => Array
(
[page] => 143
[position] => prepend
[priority] => 18
)
[2] => Array
(
[page] => 143
[position] => append
[priority] => 18
)
)
)
EDIT 1 :
I manage to work , using this code
$modify_array = array();
foreach ( $sort_result as $sort_result_key => $sort_result_value ) {
$modify_array[$sort_result_value['page']][] = $sort_result_value;
}
foreach ( $modify_array as $key => $value ) {
$filter_array[$key]['both_yes'] = array_keys(array_column($value, 'position'),'both');
$filter_array[$key]['prepend_yes'] = array_keys( array_column($value, 'position'),'prepend');
$filter_array[$key]['append_yes'] = array_keys(array_column($value, 'position'),'append');
}
foreach ( $filter_array as $filter_array_key => $filter_array_value ) {
if ( ! empty( $filter_array_value['both_yes'])) {
$a = $filter_array_value['both_yes'][0];
$final_array[] = $modify_array[$filter_array_key][$a];
} else {
if ( ! empty( $filter_array_value['prepend_yes'])) {
$b = $filter_array_value['prepend_yes'][0];
$final_array[] = $modify_array[$filter_array_key][$b];
}
if ( ! empty( $filter_array_value['append_yes'])) {
$c = $filter_array_value['append_yes'][0];
$final_array[] = $modify_array[$filter_array_key][$c];
}
}
}
Edit 2 : var_export
array ( 32 => array ( 0 => array ( 'page' => '32', 'position' => 'append', 'priority' => '1', ), 1 => array ( 'page' => '32', 'position' => 'append', 'priority' => '2', ), 2 => array ( 'page' => '32', 'position' => 'prepend', 'priority' => '3', ), 3 => array ( 'page' => '32', 'position' => 'both', 'priority' => '3', ), 4 => array ( 'page' => '32', 'position' => 'prepend', 'priority' => '4', ), ), 143 => array ( 0 => array ( 'page' => '143', 'position' => 'prepend', 'priority' => '18', ), 1 => array ( 'page' => '143', 'position' => 'append', 'priority' => '18', ), 2 => array ( 'page' => '143', 'position' => 'prepend', 'priority' => '19', ), ), )
I think the lowest time complexity that I can boil this task down to uses 1 full loop of your input array followed by a loop of the grouped data with a nested loop to isolate the rows with the lowest priority value.
The first loop does the grouping and potentially sheds worthless non-both rows for a trivial memory savings.
The second loop iterates the page groups, then the inner loop favors both rows and only uses non-both rows if there are no both rows. The if and elseif ensure that only the rows with the lowest priority number are retained. I added a rsort() call with the assumption that you want prepend rows before append rows. If the position values don't need to be prioritized, then omit the condition block containing the rsort() call.
Code: (Demo)
$array = [
['page' => '32', 'position' => 'append', 'priority' => '1'],
['page' => '32', 'position' => 'append', 'priority' => '2'],
['page' => '32', 'position' => 'prepend', 'priority' => '3'],
['page' => '32', 'position' => 'both', 'priority' => '3'],
['page' => '32', 'position' => 'prepend', 'priority' => '4'],
['page' => '143', 'position' => 'prepend', 'priority' => '18'],
['page' => '143', 'position' => 'append', 'priority' => '18'],
['page' => '143', 'position' => 'prepend', 'priority' => '19'],
];
$result = [];
foreach ($array as $row) {
if (!isset($result[$row['page']])) {
$result[$row['page']] = ['both' => [], 'non-both' => []];
}
if ($row['position'] !== 'both') {
if ($result[$row['page']]['both']) {
continue; // nothing worth doing in this case, ignore the row
} else {
$result[$row['page']]['non-both'][] = $row;
}
} else {
$result[$row['page']]['both'][] = $row;
}
}
foreach ($result as $page => $rows) {
$keep = [];
foreach ($rows['both'] ?: $rows['non-both'] as $row) {
if (!$keep || $row['priority'] < $keep[0]['priority']) {
$keep = [$row];
} elseif ($row['priority'] === $keep[0]['priority']) {
$keep[] = $row;
}
}
if ($keep[0]['position'] !== 'both') {
rsort($keep); // assuming you need prepend to occur before append
}
$result[$page] = $keep;
}
var_export($result);
I want to modify the existing array to a particular format please see the below array what i have and what i want
I have array as :
Array
(
[0] => Array
(
[block_id] => 1
[title] => Test1
[identifier] => test1
[content] => some test data
[creation_time] => 2019-09-03 09:47:35
[update_time] => 2019-09-03 09:47:35
[is_active] => 1
)
[1] => Array
(
[block_id] => 2
[title] => test2
[identifier] => twst2
[content] => dfdsffsdfsdfsfsdf
[creation_time] => 2019-09-03 09:48:03
[update_time] => 2019-09-03 09:48:03
[is_active] => 1
)
)
And I want this array as :
$options = [
['value' => 'test1', 'label' => __('Test1')],
['value' => 'test2', 'label' => __('Test2')],
['value' => 'test3', 'label' => __('Test3')],
['value' => 'test4', 'label' => __('Test4')],
['value' => 'test5', 'label' => __('Test5')],
['value' => 'test6', 'label' => __('Test6')]
];
Try this Solution.
$data = Array ( Array
(
'block_id' => 1,
'title' => 'Test1'
), Array
(
'block_id' => 2,
'title' => 'test2'
)
);
foreach($data as $k => $val){
$options[$k]['value'] = $val['title'];
$options[$k]['label'] = '__("'.ucfirst($val['title']).'")';
}
echo "<pre>";
print_r( $options);
Expected Result is
Array
(
[0] => Array
(
[value] => Test1
[label] => __("Test1")
)
[1] => Array
(
[value] => test2
[label] => __("Test2")
)
)
If $array is your array, then
foreach ($array as $k => $v)
{
$options[] = [ 'value' => $v['identifier'], 'label' => "__('" . $v['title'] . "')"];
}
If you are trying "to modify the existing array to a particular format" , next approach may help. When you precede $value with &, the $value will be assigned by reference and you can directly modify it.
<?php
foreach($array as &$value) {
$value = array(
'value' => $value["identifier"],
'label' => "__('".$value["title"]."')"
);
};
unset($value);
?>
Try this Solution.
foreach ($array as $k => $val)
{
$options[] = [ 'val' => $val['identifier'], 'label' => "__('" . $val['title'] . "')"];
}
Here is an array. Once a new element comes in with parent_uuid, I need to add that to the corresponding position, that is to the children of the item which has uuid value as parent_uuid value. The children then can have other children and if that is specified, I need to insert it to the particular parent. I think for this I need to search to the multidimensional array with the parent_uuid value. How can I do this and insert in PHP?
Array
(
[0] => Array
(
[id] => 1
[uuid] => ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9
[parent_uuid] =>
[name] => First Parent
[children] => Array
(
)
)
[1] => Array
(
[id] => 2
[uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
[parent_uuid] =>
[name] => Second Parent
[children] => Array
(
[0] => Array
(
[id] => 3
[uuid] => f87c6d5c-93ec-40bf-a04d-c925dd1e0aca
[parent_uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
[name] => First Child
[children] => Array
(
)
)
[1] => Array
(
[id] => 4
[uuid] => cb2b3d9d-867c-40a0-9254-05b466859db1
[parent_uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
[name] => Second Child
[children] => Array
(
)
)
)
)
)
I think you need some kind of recursive function, here is my messy example.
<?php
header('Content-type: text/plain');
$data = array (
0 =>
array (
'id' => 1,
'uuid' => 'ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9',
'parent_uuid' => '',
'name' => 'First Parent',
'children' =>
array (
),
),
1 =>
array (
'id' => 2,
'uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
'parent_uuid' => '',
'name' => 'Second Parent',
'children' =>
array (
0 =>
array (
'id' => 3,
'uuid' => 'f87c6d5c-93ec-40bf-a04d-c925dd1e0aca',
'parent_uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
'name' => 'First Child',
'children' =>
array (
),
),
1 =>
array (
'id' => 4,
'uuid' => 'cb2b3d9d-867c-40a0-9254-05b466859db1',
'parent_uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
'name' => 'Second Child',
'children' =>
array (
),
),
),
),
);
function arrayAddChild(&$data, $child) {
if (!isset($data) || !is_array($data) || empty($data)) {
return false;
}
foreach ($data as $key => $value) {
if ($value['uuid'] === $child['parent_uuid']) {
$data[$key]['children'][] = $child;
return true;
}
if(arrayAddChild($data[$key]['children'], $child)) {
return true;
}
}
return false;
}
var_export(arrayAddChild($data, [
'id' => 31,
'uuid' => '31',
'parent_uuid' => 'cb2b3d9d-867c-40a0-9254-05b466859db1',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 32,
'uuid' => '32',
'parent_uuid' => '31',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 33,
'uuid' => '33',
'parent_uuid' => '32',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 34,
'uuid' => '34',
'parent_uuid' => '33',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 35,
'uuid' => '35',
'parent_uuid' => '34',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 36,
'uuid' => '36',
'parent_uuid' => '35',
'name' => 'Second Child',
'children' => []
]
));
var_export($data);
this is the structure you need
$Array["ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9"]['name'] = "First Parent";
$Array["ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9"]['children'] = [];
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['name'] = "Second Parent";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["f87c6d5c-93ec-40bf-a04d-c925dd1e0aca"]['name'] = "First Child";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["f87c6d5c-93ec-40bf-a04d-c925dd1e0aca"]['children'] = [];
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["cb2b3d9d-867c-40a0-9254-05b466859db1"]['name'] = "Second Child";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["cb2b3d9d-867c-40a0-9254-05b466859db1"]['children'] = [];
and this is if you really need 'name' or any complementary info you need to store with each item. If it is just about a tree structure of uid, get rid of 'name' and 'children' keys
have not found a standard php function to recursively search for a given key (anyone ?)
so here is the function you need
function insertItem($newItem,$uidParent,$array) {
foreach ($array as $uid => $content) {
if ($uid == $uidParent) { // parent found, item insert
$array[$uid]['children'][$newItem['uid']]['name'] = $newItem['name'];
$array[$uid]['children'][$newItem['uid']]['children'] = [];
} elseif (!empty($content['children'])) { // recursively search the tree
$array[$uid]['children'] = insertItem($newItem,$uidParent,$content['children']);
}
}
return $array;
}
$newItem['name'] = "new item";
$newItem['uid'] = "f87c6d5c-93ec-40bf-a04d-c925dd1e0aca";
$uidParent = "cb2b3d9d-867c-40a0-9254-05b466859db1";
$Array = insertItem($newItem,$uidParent,$Array);
sandbox here
Currently, I have 2 multidimensional array and I'm looking to combine them into one giant array where the value's name in array 1 matches the value's name in array 2.
The array's look as followed...
Array1
(
[0] => Array
(
[id] => 1
[name] => test1
[desc] => test_desc
[quantity] => 3
)
[1] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Array2
(
[0] => Array
(
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
)
I'm looking to merge the arrays where the 'name' column in array1 matches in array2 and also combine the columns in array's 1 & 2 into the final array. This should look like...
FinalArray
(
[0] => Array
(
[id] => 1
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
[quantity] => 3
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
[2] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Where the "test1" combines the different columns across the 2 arrays into a new array inside the "FinalArray". I've tried researching some ideas with array_merge and array_merge_recursive but I'm not entirely sure if I'm going in the correct direction. Thanks in advance.
Try like this
$array1=[['id' => 1,'name' => 'test1','desc' => 'test_desc','quantity' => 3],
['id' => 2,'name' => 'test2','desc' => 'test_desc','quantity' => 33]];
$array2=[['holder' => 'John','name' => 'test1','desc' => 'test_desc','location' => 'ATL'],
['holder' => 'Jackie','name' => 'test3','desc' => 'test_desc','location' => 'SF']];
$final=[];
foreach ($array1 as $key1=>$data1){
foreach ($array2 as $key2=>$data2){
if($data1['name']==$data2['name']){
$final[]=$data1+$data2;
unset($array1[$key1]);
unset($array2[$key2]);
}
}
}
if(!empty($array1)){
foreach ($array1 as $value){
$final[]=$value;
}
}
if(!empty($array2)){
foreach ($array2 as $value){
$final[]=$value;
}
}
It will give output as
One more solution
function merge_by_name(array $arr1, array $arr2) {
$result = [];
foreach ($arr1 as $value) {
$key = array_search($value['name'], array_column($arr2, 'name'));
if($key !== false) {
$result[] = array_merge($value, $arr2[$key]);
unset($arr2[$key]);
} else {
$result[] = $value;
}
}
$result = array_merge($result, $arr2);
return $result;
}
Test
$arr1 = [
[
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3
],
[
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33
],
];
$arr2 = [
[
'holder' => 'John',
'name' => 'test1',
'desc' => 'test_desc',
'location' => 'ATL'
],
[
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF'
],
];
var_export(merge_by_name($arr1, $arr2));
Result
array (
0 =>
array (
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3,
'holder' => 'John',
'location' => 'ATL',
),
1 =>
array (
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33,
),
2 =>
array (
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF',
),
)
Trying to add a bunch of array values together, keeping the ID value....
I thought I could use a basic foreach with a += operator, but it's not working out.
Here are my arrays:
Array(
[0] => Array(
[246] => Array(
[amount] => 2
)
)
)
Array(
[0] => Array(
[245] => Array(
[amount] => 1
)
)
)
Array(
[0] => Array(
[243] => Array(
[amount] => 2
)
)
)
Array(
[0] => Array(
[245] => Array(
[amount] => 1
)
)
)
Array(
[0] => Array(
[243] => Array(
[amount] => 2
)
)
)
What I'm trying to get is:
array(
'243' => '4',
'245' => '2',
'246' => '2',
);
And here's what I was attempting:
$sumArray = array();
foreach ($orgArray[0] as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
$sumArray[$k]+=$value;
}
}
Here is what I'm getting:
Array
(
[243] => 2
)
You simply need to modify your foreach loops as you're trying to set $key which is the index of the arrays which for the example above would be 0,1,2,3...etc not 246,245,243...etc as you expect.
This is what you want.
$orgArray = [
[246 => ['amount' => 2]],
[245 => ['amount' => 1]],
[243 => ['amount' => 2]],
[245 => ['amount' => 1]],
[243 => ['amount' => 2]],
];
$sumArray = array();
foreach ($orgArray as $k => $subArray) {
foreach ($subArray as $id => $item) {
if (!isset($sumArray[$id])) {
$sumArray[$id] = 0;
}
$sumArray[$id] += $item['amount'];
}
}
Note: The above [] array identifier is assuming you're using the correct php version that allows it, otherwise you'd have to change them to array()
Which returns:
Array
(
[246] => 2
[245] => 2
[243] => 4
)
As expected.
EXAMPLE