How to check the condition in given three array - php

I am having three arrays
topicsSelected
relavantGroups
topicAssingned
$topicsSelected = [ "T-100","T-600"];
$relavantGroups = [[ "id" => "G-001","name" => "3 A","active"=> false ], ["id"=> "G-002","name"=> "3 B","active"=> false] ];
$topicAssingned = [
"G-001" => [
"groupID" => "G-001",
"groupName" => "3 A",
"topics" => [
"T-100" => [
"topicID" => "T-100"
],
"T-200" => [
"topicID" => "T-200"
]
]
],
"G-002" => [
"groupID" => "G-002",
"groupName" => "3 B",
"topics" => [
"T-400" => [
"topicID" => "T-400"
],
"T-500" => [
"topicID" => "T-500"
]
]
],
];
$topicsSelected array values(T-100 or T-600) at least one value should present in $topicAssingned array, based on groupID(G-001). $topicAssingned under topics , topicID : T-100 is present , so Disable : D
$topicsSelected array values(T-100 or T-600) at least one value should present in $topicAssingned array, based on groupID(G-002). $topicAssingned under topics , topicID : T-100 & T-600 is not present , so Disable : A
Expected output:
[
"id": "G-001",
"name": "3 A",
"active": false,
"Disable" : "D"
],
[
"id": "G-002",
"name": "3 B",
"active": false,
"Disable" : "A"
]
My Code
foreach ($relavantGroups as &$g) {
$found = false;
foreach ($topicAssingned as $key => $assigned) {
if ($key === $g["id"]) {
$found = true;
break;
}
}
$g["disable"] = $found ? "D" : "A";
}
echo "<pre>";
print_r($relavantGroups);
My Output
Array
(
[0] => Array
(
[id] => G-001
[name] => 3 A
[active] =>
[disable] => D
)
[1] => Array
(
[id] => G-002
[name] => 3 B
[active] =>
[disable] => D
)
)

You can try this snippet,
foreach ($relavantGroups as &$g) {
$found = false;
foreach ($topicAssingned as $key => $assigned) {
if ($key === $g["id"]) {
$temp = array_keys($assigned['topics']); // fetching all topic ids
$intr = array_intersect($topicsSelected, $temp); // checking if there are any matching values between topicSelected and traversed values
$found = (!empty($intr) ? true : false); // if found return and break
break;
}
}
$g["disable"] = $found ? "D" : "A";
}
print_r($relavantGroups);
array_intersect — Computes the intersection of arrays
array_keys — Return all the keys or a subset of the keys of an array
Output
Array
(
[0] => Array
(
[id] => G-001
[name] => 3 A
[active] =>
[disable] => D
)
[1] => Array
(
[id] => G-002
[name] => 3 B
[active] =>
[disable] => A
)
)
Demo

Related

unset values null array multidimensional php [duplicate]

This question already has answers here:
Recursively remove empty elements and subarrays from a multi-dimensional array
(8 answers)
How to remove null values in multi-dimensional array?
(7 answers)
Closed 1 year ago.
this is my first time on stackoverflow so sorry if I do something wrong. I would also appreciate your advice.
I have the next Array:
$dataPayment= [
"operationType" => null
"terminal" => 12345
"payment" => array:14 [
"terminal" => 12345
"order" => "1234519997"
"amount" => 100
"currency" => "EUR"
"secure" => 0
"idUser" => 123456789"
"tokenUser" => "zidkeKeu68Kld"
"urlOk" => null
"urlKo" => null
"originalIp" => "1.130.151.28"
"methodId" => 1
"trxType" => "N"
"userInteraction" => 1
"scaException" => "MIT"
]
"subscription" => array:2 [
"startDate" => null
"endDate" => null
]
]
And I want delete the null values. With array_filter also delete values 0, but I need those values 0. I tried with the following method:
private function arrayUnset( $dataPayment )
{
foreach( $dataPayment as $key => $value )
{
if( is_array( $dataPayment[ $key ] ) )
{
$this->arrayUnset( $dataPayment[ $key ] );
}
if( $value === null || $value === "" )
{
unset( $dataPayment[ $key ] );
}
}
return $dataPayment;
}
But, only delete the first value.
$dataPayment = [
"terminal" => 12345
"payment" => array:14 [
"terminal" => 12345
"order" => "1234519997"
"amount" => 100
"currency" => "EUR"
"secure" => 0
"idUser" => 123456789"
"tokenUser" => "zidkeKeu68Kld"
"urlOk" => null
"urlKo" => null
"originalIp" => "1.130.151.28"
"methodId" => 1
"trxType" => "N"
"userInteraction" => 1
"scaException" => "MIT"
]
"subscription" => array:2 [
"startDate" => null
"endDate" => null
]
]
And I would need the following array:
$dataPayment = [
"terminal" => 12345
"payment" => array:14 [
"terminal" => 12345
"order" => "1234519997"
"amount" => 100
"currency" => "EUR"
"secure" => 0
"idUser" => 123456789"
"tokenUser" => "zidkeKeu68Kld"
"originalIp" => "1.130.151.28"
"methodId" => 1
"trxType" => "N"
"userInteraction" => 1
"scaException" => "MIT"
]
]
Can you help me please?. Thanks.
That code does not seem to delete the 0 valued entries, but you do need to pass the parameter by reference if you want to see the changes in the calling process
$Payment = [
"operationType" => null,
"terminal" => 12345,
"payment" => [
"terminal" => 12345,
"order" => "1234519997",
"amount" => 100,
"currency" => "EUR",
"secure" => 0,
"idUser" => 123456789,
"tokenUser" => "zidkeKeu68Kld",
"urlOk" => null,
"urlKo" => null,
"originalIp" => "1.130.151.28",
"methodId" => 1,
"trxType" => "N",
"userInteraction" => 1,
"scaException" => "MIT"
],
"subscription" => [
"startDate" => null,
"endDate" => null
]
];
class xxx
{
private function arrayUnset( &$dataPayment )
{
foreach( $dataPayment as $key => $value ) {
if( is_array( $dataPayment[ $key ] ) ) {
$this->arrayUnset( $dataPayment[ $key ] );
}
if( $value === null || $value === "" ) {
unset( $dataPayment[ $key ] );
}
}
return $dataPayment;
}
public function zzz($data)
{
return $this->arrayUnset($data);
}
}
$obj = new xxx;
print_r($obj->zzz($Payment));
RESULTS
Array
(
[terminal] => 12345
[payment] => Array
(
[terminal] => 12345
[order] => 1234519997
[amount] => 100
[currency] => EUR
[secure] => 0
[idUser] => 123456789
[tokenUser] => zidkeKeu68Kld
[originalIp] => 1.130.151.28
[methodId] => 1
[trxType] => N
[userInteraction] => 1
[scaException] => MIT
)
[subscription] => Array
(
)
)
You should passing argument by reference.
private function arrayUnset( &$dataPayment )
{
foreach( $dataPayment as $key => $value )
{
if( is_array( $dataPayment[ $key ] ) )
{
$dataPayment[ $key ] = $this->arrayUnset($value);
}
if( $value === null || $value === "" )
{
unset( $dataPayment[ $key ] );
}
}
return $dataPayment;
}
Array filters remove null elements, so map your array using mapWithKeys, if each property is an array, use array_filter(). Run a secondary filter, to remove the empty array.
$collection = collect($dataPayment);
$result = $collection->mapWithKeys(function ($item, $key) {
if (is_array($item)) {
$item = array_filter($item);
}
return [$key => $item];
})->filter()->all();
This should produce the expected results. If any problems with the code, please write.
You are not storing the return from your recursive calls.
Try:
<?php
$Payment = [
"operationType" => null,
"terminal" => 12345,
"payment" => [
"terminal" => 12345,
"order" => "1234519997",
"amount" => 100,
"currency" => "EUR",
"secure" => 0,
"idUser" => 123456789,
"tokenUser" => "zidkeKeu68Kld",
"urlOk" => null,
"urlKo" => null,
"originalIp" => "1.130.151.28",
"methodId" => 1,
"trxType" => "N",
"userInteraction" => 1,
"scaException" => "MIT"
],
"subscription" => [
"startDate" => null,
"endDate" => null
]
];
function arrayUnset($dataPayment) {
foreach($dataPayment as $key => $value)
if(is_array($dataPayment[$key]))
$dataPayment[$key]=arrayUnset($dataPayment[$key]);
else if ($value==null || $value=="")
unset($dataPayment[$key]);
return $dataPayment;
}
print_r(arrayUnset($Payment));
Output:
Array
(
[terminal] => 12345
[payment] => Array
(
[terminal] => 12345
[order] => 1234519997
[amount] => 100
[currency] => EUR
[secure] => 0
[idUser] => 123456789
[tokenUser] => zidkeKeu68Kld
[originalIp] => 1.130.151.28
[methodId] => 1
[trxType] => N
[userInteraction] => 1
[scaException] => MIT
)
[subscription] => Array
(
)
)
Teh Playground!

How to remove any sub array and keep only two top levels of a multidimensional array?

I need to modify an array with subarrays and keep only the top two arrays (array -> results - x) and remove any subarray below. For example array "location" & "syncState" should be removed.
Original array:
$device_array = [
"totalCount" => "3",
"results" => [
[
"id" => "2",
"serialNumber" => "DX",
"location" => ["id" => "5", "locationName" => "US"]
],
[
"id" => "4",
"serialNumber" => "DM",
"syncState" => ["id" => "7", "locationName" => "DE"]
],
[
"id" => "5",
"serialNumber" => "C0"
]
]
];
The array should look like this:
Array
(
[totalCount] => 3
[results] => Array
(
[0] => Array
(
[id] => 2
[serialNumber] => DX
)
[1] => Array
(
[id] => 4
[serialNumber] => DM
)
[2] => Array
(
[id] => 5
[serialNumber] => C0
)
)
)
I'm trying to loop through the arrays (sub arrays included) but I can't remove all of the subarrays that sit under $device_array['results'][x].
foreach ($device_array as $key => $value) {
if(is_array($value)) {
unset($device_array['results'][0]['location']);
}
}
You can just loop the results subarray directly and write a custom filter which will modify each entry by reference. Any of the associative elements that hold array type data will be filtered out.
Code: (Demo)
$array = [
"totalCount" => "3",
"results" => [
[
"id" => "2",
"serialNumber" => "DX",
"location" => ["id" => "5", "locationName" => "US"]
],
[
"id" => "4",
"serialNumber" => "DM",
"syncState" => ["id" => "7", "locationName" => "DE"]
],
[
"id" => "5",
"serialNumber" => "C0"
]
]
];
foreach ($array['results'] as &$entry) {
$entry = array_filter($entry, 'is_scalar');
}
var_export($array);
Output:
array (
'totalCount' => '3',
'results' =>
array (
0 =>
array (
'id' => '2',
'serialNumber' => 'DX',
),
1 =>
array (
'id' => '4',
'serialNumber' => 'DM',
),
2 =>
array (
'id' => '5',
'serialNumber' => 'C0',
),
),
)
Or completely functional style: (Demo)
$array['results'] = array_map(
function($entry) {
return array_filter($entry, 'is_scalar');
},
$array['results']
);
var_export($array);
This is how you obtain the output, but I am not so sure if this is what you need in your case
<?php
$array = [
'total' => 2,
'result' => [
[
'id' => 1,
'serialNumber' => 'DX',
'location' => ['id'=>1, 'locationName'=>'US']
],
[
'id' => 2 ,
'serialNumber' => 'DO',
'syncState' => ['id'=>7, 'locationName'=>'DE']
]
]
];
foreach( $array['result'] as $key => $value ){
foreach($value as $key2=>$subarray){
if(is_array($subarray)){
unset($value[$key2]);
}
}
$array['result'][$key] = $value;
}
print_r($array);

Sorting Multidimensional array several levels

I am currently trying to sort a multidimensional array by its totalPoints. Each array lineupSet has an n amount of items. I am trying to get the lineupSet with the the highest total totalPoints. How could I achieve most efficiently? the below is sudocode and therefore not working. Unsure how to approach this.
Code
public function getHighestTotalPoints($testArray)
{
if (isset($testArray) && !empty($testArray)) {
uasort($testArray, function ($a, $b) {
return $a['lineupSet']['formula']['totalPoints'] <=> $b['lineupSet']['formula']['totalPoints'] ;
});
return array_reverse($testArray);
}
return null;
}
$testArray = [[
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.61,
],
"name" => "test1",
], [
"formula" => [
"totalPoints" => 201.17,
],
"name" => "test2",
]], [
"formula" => [
"totalPoints" => 5.01,
],
"name" => "test3",
]],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 220.66,
],
"name" => "test1",
], [
"formula" => [
"totalPoints" => 214.76,
],
"name" => "test2",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.71,
],
"name" => "test1",
], [
"formula" => [
"totalPoints" => 204.43,
],
"name" => "test2",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.48,
],
"name" => "test1",
], [
"formula" => [
"totalPoints" => 203.51,
],
"name" => "test2",
]],
],
]];
Desired result:
[0] => Array
(
[lineupSet] => Array
(
[0] => Array
(
[0] => Array
(
[formula] => Array
(
[totalPoints] => 220.66
)
[name] => test1
)
[1] => Array
(
[formula] => Array
(
[totalPoints] => 214.76
)
[name] => test2
)
)
)
)
You can use usort to sort the array according to a custom function. This function determines the totalPoints for a given lineupSet:
function sum_points($v) {
$totalPoints = 0;
foreach ($v['lineupSet'] as $lset) {
if (isset($lset['formula'])) {
$totalPoints += $lset['formula']['totalPoints'];
}
else {
foreach ($lset as $l) {
$totalPoints += $l['formula']['totalPoints'];
}
}
}
return $totalPoints;
}
To sort descending (so the maximum total points is in the first entry of the array), we then use a sort function which returns a positive number when the second value's totalPoints are bigger than the first, a negative number when it's smaller and 0 when they are the same:
function sort_points($a, $b) {
return sum_points($b) - sum_points($a);
}
Finally we call usort with this function and output the first element of the array:
usort($testArray, 'sort_points');
print_r($testArray[0]);
Output:
Array (
[lineupSet] => Array
(
[0] => Array
(
[0] => Array
(
[formula] => Array
(
[totalPoints] => 220.66
)
[name] => test1
)
[1] => Array
(
[formula] => Array
(
[totalPoints] => 214.76
)
[name] => test2
)
)
)
)
Demo on 3v4l.org

how to sort array data in alphabetic key order in php

my collection of data in array which is shown below the index key is A,B,C but i want to store these key in "key" and its key letter's words in "dishes" key
array:3 [
"A" => array:4 [
0 => 37
1 => "Algerian"
2 => 6
3 => "American"
]
"B" => array:6 [
0 => 27
1 => "Belgian"
2 => 20
3 => "Brazilian"
]
and so on..
i wanna sort this array like aplhabetic order as shown below
array:10 [
0 => array:2 [
"key" => "A"
"dishes" => array:2 [
0=>array:2[
"id" => 37
"type" => "Algerian"
],
1=>array:2[
"id" => 6
"type" => "American"
]
]
]
1 => array:2 [
"key" => "B"
"dishes" => array:2 [
0=>array:2[
"id" => 27
"type" => "Belgian"
],
1=>array:2[
"id" => 20
"type" => "Brazilian"
]
]
]
and so on...
This would be a possible solution:
<?php
$input = [
'A' => [
0 => 37,
1 => "Algerian",
2 => 6,
3 => "American"
],
'B' => [
0 => 27,
1 => "Belgian",
2 => 20,
3 => "Brazilian"
]
];
$output = [];
array_walk($input, function($values, $key) use (&$output) {
$entry = [
'key' => $key,
'dishes' => []
];
foreach(array_chunk($values, 2) as $chunk) {
$entry['dishes'][] = [
'id' => $chunk[0],
'type' => $chunk[1]
];
}
$output[] = $entry;
});
print_r($output);
The output of above code obviously is:
Array
(
[0] => Array
(
[key] => A
[dishes] => Array
(
[0] => Array
(
[id] => 37
[type] => Algerian
)
[1] => Array
(
[id] => 6
[type] => American
)
)
)
[1] => Array
(
[key] => B
[dishes] => Array
(
[0] => Array
(
[id] => 27
[type] => Belgian
)
[1] => Array
(
[id] => 20
[type] => Brazilian
)
)
)
)
You have to loop through the original array to create your new structure. Then you can use the ksort function to sort them.
$newArr = new array();
for ($arr as $elem) {
$dishArr = new array();
for($elem['dishes'] as $dish) {
$dishArr[] = $dish['id'];
$dishArr[] = $dish['type'];
}
$newArr[$elem['key']] = $dishArr;
}
ksort($newArr);

Compare value in three array and get specific value in php

I am comparing three value in an array and i am getting all value.
How can i output specific value or value that i only want to output
Because i want to output value that i only nedeed.
I have this code:
<?php
$participants = [
[ 'calleridnum' => 1,
'callee' => 'yay'
],
[ 'calleridnum' => 2,
'callee' => 'yay'
],
[ 'calleridnum' => 3,
'callee' => 'yay'
]
];
$conferance_participants = [
[ 'uid' => 1,
'caller' => 'yay2',
'dit' => 'deze'
],
[ 'uid' => 2,
'caller' => 'test',
'dit' => 'wew'
]
];
$contacts = [
[ 'name' => 1,
'test' => 'yay2',
'limit' => 1
],
[ 'name' => 2,
'test' => 'yay2',
'limit' => 1
]
];
foreach ($participants as $participant=>$p) {
foreach ($conferance_participants as $conferance_participant=>$cp) {
foreach ($contacts as $contact=>$cs) {
if (($p['calleridnum'] == $cp['uid']) && ($cp['uid'] == $cs['name'])){
$conferance_participants[$conferance_participant] = array_merge(
$participants[$participant],
$conferance_participants[$conferance_participant],
$contacts[$contact]
);
}
}
}
}
echo "<pre>";
print_r($conferance_participants);
echo "</pre>";
?>
and my output is:
Array
(
[0] => Array
(
[calleridnum] => 1
[callee] => yay
[uid] => 1
[caller] => yay2
[dit] => deze
[name] => 1
[test] => yay2
[limit] => 1
)
[1] => Array
(
[calleridnum] => 2
[callee] => yay
[uid] => 2
[caller] => test
[dit] => wew
[name] => 2
[test] => yay2
[limit] => 1
)
)
I want ot minimize my output.
I want to remove name test from the $contacts array
I also want to remove caller dit from the $conferance_participants array
so that my output will be :
Array
(
[0] => Array
(
[calleridnum] => 1
[callee] => yay
[uid] => 1
[limit] => 1
)
[1] => Array
(
[calleridnum] => 2
[callee] => yay
[uid] => 2
[limit] => 1
)
)
Your code is hard to understand,
Number of times your foreach will execute,
count($participants) * count($conferance_participants) * count($contacts);
Number of times this code's foreach will execute will be equal or less than your codes, because it will stop as soon as the match found.
Also i have created a new function, for searching in another arrays, so it will make the next person working on this code less bang his head on the desk.
Passes $conferance_participants variable's value as reference, note the & in foreach declaration so no need to worry about keys of the array.
foreach($conferance_participants as &$record) {
# find keys of corresponding array matches
$key_in_participants = _custom_search($record['uid'], $participants, 'calleridnum');
$key_in_contacts = _custom_search($record['uid'], $contacts, 'name');
# unset unwanted things
unset($record['caller'], $record['dit']);
# activate this code if you want to make false for unmatched records
/* ***********************************************************************
if($key_in_participants === false || $key_in_contacts === false) {
$record['calleridnum'] = $record['callee'] = $record['limit'] = false;
continue;
}
*********************************************************************** */
# setting required things
$record['calleridnum'] = $participants[$key_in_participants]['calleridnum'];
$record['callee'] = $participants[$key_in_participants]['callee'];
$record['limit'] = $contacts[$key_in_contacts]['limit'];
}
function _custom_search($id, $array, $key_to_search) {
foreach ($array as $key => $val) if($val[$key_to_search] === $id) return $key;
return false;
}
This will make $conferance_participants exactly as you want.
You can just unset the array keys before you merge the arrays. Then set the 'name' key again for $contacts array which is needed for the loops above.
Here is the modified code sample:
<?php
$participants = [
[ 'calleridnum' => 1,
'callee' => 'yay'
],
[ 'calleridnum' => 2,
'callee' => 'yay'
],
[ 'calleridnum' => 3,
'callee' => 'yay'
]
];
$conferance_participants = [
[ 'uid' => 1,
'caller' => 'yay2',
'dit' => 'deze'
],
[ 'uid' => 2,
'caller' => 'test',
'dit' => 'wew'
]
];
$contacts = [
[ 'name' => 1,
'test' => 'yay2',
'limit' => 1
],
[ 'name' => 2,
'test' => 'yay2',
'limit' => 1
]
];
foreach ($participants as $participant=>$p) {
foreach ($conferance_participants as $conferance_participant=>$cp) {
foreach ($contacts as $contact=>$cs) {
if (($p['calleridnum'] == $cp['uid']) && ($cp['uid'] == $cs['name'])){
unset($contacts[$contact]['name'], $contacts[$contact]['test']);
unset($conferance_participants[$conferance_participant]['caller'], $conferance_participants[$conferance_participant]['dit']);
$conferance_participants[$conferance_participant] = array_merge(
$participants[$participant],
$conferance_participants[$conferance_participant],
$contacts[$contact]
);
$contacts[$contact]['name'] = $cs['name'];
}
}
}
}
echo "<pre>";
print_r($conferance_participants);
echo "</pre>";
The output you should get:
Array
(
[0] => Array
(
[calleridnum] => 1
[callee] => yay
[uid] => 1
[limit] => 1
)
[1] => Array
(
[calleridnum] => 2
[callee] => yay
[uid] => 2
[limit] => 1
)
)
I hope that answers your question. Thanks.
After merging, you may filter only certain keys you want to be present in final result using array_intersect_key().
$keys = array_flip(['calleridnum', 'callee', 'uid', 'limit']);
$conferance_participants[$conferance_participant] =
array_intersect_key(
array_merge(
$participants[$participant],
$conferance_participants[$conferance_participant],
$contacts[$contact]
),
$keys
);

Categories