I am struggling to figure out how to remove elements from a triple nested array based on a value at the deepest level. I would like to remove any position sub-array where time == "NA". My array structure is as follows.
Array
(
[0] => Array
(
[Id] => 151601
[First_Name] => JOHN
[Last_Name] => DOE
[Location_Id] => 10
[Positions] => Array
(
[North] => Array
(
[Current_Level] => 4
[Last_Date] => 11/7/2001
[Time] => 4:15 AM
)
[East] => Array
(
[Current_Level] => 4
[Last_Date] => 7/10/2003
[Time] => 7:30 PM
)
[South] => Array
(
[Current_Level] => 2
[Last_Date] => 8/10/2007
[Time] => NA
)
[West] => Array
(
[Current_Level] => NA
[Last_Date] => NA
[Time] => NA
)
)
)
So my end result would be
Array
(
[0] => Array
(
[Id] => 151601
[First_Name] => JOHN
[Last_Name] => DOE
[Location_Id] => 10
[Positions] => Array
(
[North] => Array
(
[Current_Level] => 4
[Last_Date] => 11/7/2001
[Time] => 4:15 AM
)
[East] => Array
(
[Current_Level] => 4
[Last_Date] => 7/10/2003
[Time] => 7:30 PM
)
)
)
This is what I am currently trying but it is throwing an illegal offset type error. I think I'm just not unsetting the right thing. I can get it to echo all the correct subarrays but when I try to unset I get an offset error.
foreach($records as $record) {
foreach ($record as $value) {
if (is_array($value)) {
foreach ($value as $position) {
if($position["Time"] == "NA") {
unset($records[$record][$value]);
}
}
}
}
}
With passing array element by reference and filtering function you can reduce your code to:
foreach($records as &$record) {
$record['Positions'] = array_filter(
$record['Positions'],
function ($v) {
return $v['Time'] !== 'NA';
}
);
}
Fiddle here.
Php uses a copy of the array in the foreach. You might also use a key in the foreach and use that to unset the value in the original $records array.
foreach ($records as $keyRecord => $record) {
foreach ($record as $key => $value) {
if (is_array($value)) {
foreach ($value as $keyPosition => $position) {
if ($position["Time"] == "NA") {
unset($records[$keyRecord][$key][$keyPosition]);
}
}
}
}
}
print_r($records);
Output
Array
(
[0] => Array
(
[Id] => 151601
[First_name] => John
[Positions] => Array
(
[North] => Array
(
[Current_Level] => 4
[Last_Date] => 11/7/2001
[Time] => 4:15 AM
)
[East] => Array
(
[Current_Level] => 4
[Last_Date] => 7/10/2003
[Time] => 7:30 PM
)
)
)
)
Php demo
Related
I am trying to print part of this array, basically all the URLS [href] with "ProviderRedirect.ashx" basically [0] to [infinite]
Array
(
[name] => HC Redirect
[count] => 66
[frequency] => Daily
[version] => 14
[newdata] => 1
[lastrunstatus] => partial
[thisversionstatus] => success
[nextrun] => Sun Jan 17 2016 14:03:08 GMT+0000 (UTC)
[thisversionrun] => Sat Jan 16 2016 14:03:08 GMT+0000 (UTC)
[results] => Array
(
[collection1] => Array
(
[0] => Array
(
[Hotel Search] => Array
(
[href] => https://www.domain.com/ProviderRedirect.ashx?key=0.6359329.272723160.5179.GBP.1729297590&saving=410&source=32-0
[text] => View Deal
)
[index] => 1
[url] => https://www.domain.com/Hotels/Search?destination=place:London&checkin=2016-09-02&checkout=2016-09-09&Rooms=1&adults_1=2&languageCode=EN¤cyCode=GBP&pageSize=50
)
[1] => Array
(
[Hotel Search] => Array
(
[href] => https://www.domain.com/ProviderRedirect.ashx?key=0.21199849.272723130.457.GBP.753573779&source=32-0
[text] => View Deal
)
[index] => 2
[url] => https://www.domain.com/Hotels/Search?destination=place:London&checkin=2016-09-02&checkout=2016-09-09&Rooms=1&adults_1=2&languageCode=EN¤cyCode=GBP&pageSize=50
)
[2] => Array
(
[Hotel Search] => Array
(
[href] => https://www.domain.com/ProviderRedirect.ashx?key=0.23906211.272723157.1326.GBP.2008823249&source=32-0
[text] => View Deal
)
[index] => 3
[url] => https://www.domain.com/Hotels/Search?destination=place:London&checkin=2016-09-02&checkout=2016-09-09&Rooms=1&adults_1=2&languageCode=EN¤cyCode=GBP&pageSize=50
)
[3] => Array
(
[Hotel Search] => Array
(
[href] => https://www.domain.com/ProviderRedirect.ashx?key=0.5242811.272723157.3854.GBP.1642352834&source=32-0
[text] => View Deal
)
[index] => 4
[url] => https://www.domain.com/Hotels/Search?destination=place:London&checkin=2016-09-02&checkout=2016-09-09&Rooms=1&adults_1=2&languageCode=EN¤cyCode=GBP&pageSize=50
)
[4] => Array
(
[Hotel Search] => Array
(
[href] => https://www.domain.com/ProviderRedirect.ashx?key=0.675524.272723160.1457.GBP.2121712597&saving=18&source=32-0
[text] => View Deal
)
[index] => 5
[url] => https://www.domain.com/Hotels/Search?destination=place:London&checkin=2016-09-02&checkout=2016-09-09&Rooms=1&adults_1=2&languageCode=EN¤cyCode=GBP&pageSize=50
)
[5] => Array
(
[Hotel Search] => Array
(
[href] => https://www.domain.com/ProviderRedirect.ashx?key=0.5743724.272723155.847.GBP.1001086600&source=32-0
[text] => View Deal
)
[index] => 6
[url] => https://www.domain.com/Hotels/Search?destination=place:London&checkin=2016-09-02&checkout=2016-09-09&Rooms=1&adults_1=2&languageCode=EN¤cyCode=GBP&pageSize=50
)
[6] => Array
Either use array_walk_recursive() function or write your own function to recursively traverse the array and print all urls.
Suppose $arr is your array.
Method(1):
array_walk_recursive($arr, function($item, $key) {
if ($key == "href") {
echo $item . "<br />";
}
});
Method(2):
function process_array($array){
foreach($array as $key => $value){
if(is_array($value)){
process_array($value);
}else{
if($key == "href"){
echo $value . "<br />";
}
}
}
}
process_array($arr);
$items = array(
'results' => array(
'collection1'=> array(
array(
'hotel_search'=>array(
'href'=>'value'
),
'index'=>'value'
),
array(
'hotel_search'=>array(
'href'=>'value'
),
'index'=>'value'
)
)
)
);
$collection1 = $items['results']['collection1'];
foreach($collection1 as $collection) {
printf("%s", $collection['hotel_search']['href']);
}
You would need to loop over the results array though to avoid hardcoding
If all you need to do is print the values, array_walk_recursive would do the job:
array_walk_recursive($array, function($item, $key) {
if ('href' === $key) {
echo "$item\n";
}
});
I just pasted my sample input & output.
Sample Input:
Array
(
[0] => Array
(
[id] => 1
[msisdn] => 10
[sc] => 8155
)
[1] => Array
(
[id] => 2
[msisdn] => 20
[sc] => 22020
)
[2] => Array
(
[id] => 3
[msisdn] => 10
[sc] => 8155
)
[3] => Array
(
[id] => 4
[msisdn] => 10
[sc] => 8155
)
[4] => Array
(
[id] => 5
[msisdn] => 20
[sc] => 22020
)
[5] => Array
(
[id] => 6
[msisdn] => 30
[sc] => 22020
)
)
Sample Output:
Array
(
[0] => Array
(
[id] => 1,3,4
[msisdn] => 10
[sc] => 8155
)
[1] => Array
(
[id] => 2,5
[msisdn] => 20
[sc] => 22020
)
[2] => Array
(
[id] => 6
[msisdn] => 30
[sc] => 8155
)
)
Just make that particular value that key, then just concatenate when already pushed/exists:
$new_array = array();
foreach ($array as $value) {
if(!isset($new_array[$value['msisdn']])) {
// if not yet pushed, just initialize
$new_array[$value['msisdn']] = $value;
} else {
// if already inside, then just concatenate
$new_array[$value['msisdn']]['id'] .= ', ' . $value['id'];
}
}
$new_array = array_values($new_array);
echo '<pre>';
print_r($new_array);
Sample Output
Live on codepad: http://codepad.org/0fw9k2w9
You can use the fact that in PHP array is an hash map. By creating an intermediate array you can solve this in O(n) time.
$merged = array();
foreach($array as $v) {
$merged[$v['msisdn']][$v['sc']] [] = $v['id'];
}
$final = array();
foreach($merged as $msisdn=>$v) {
foreach($v as $sc=>$ids) {
$final [] = array('msisdn'=>$msisdn,'sc'=>$sc,'id'=>$ids);
}
}
Please refer to array below. What I would like to do is to get the total of the values of index zero under 21 and 23 divided by the number of zeros. It is like getting their average.
Array
(
[21] => Array
(
[0] => 3.5
[65] => Array
(
[0] => 44.125
)
[150] => Array
(
[0] => 15.25
)
[151] => Array
(
[0] => 17.333333333333
)
)
[23] => Array
(
[0] => 0
[166] => Array
(
[0] => 26
)
[172] => Array
(
[0] =>
)
[182] => Array
(
[0] => 20.333333333333
)
[183] => Array
(
[0] => 24.125
)
)
)
Then format it to this
Array
(
[21] => Array
(
[0] => Average for 21
[65] => Array
(
[0] => 44.125
)
[150] => Array
(
[0] => 15.25
)
[151] => Array
(
[0] => 17.333333333333
)
)
[23] => Array
(
[0] => Average for 23
[166] => Array
(
[0] => 26
)
[172] => Array
(
[0] =>
)
[182] => Array
(
[0] => 20.333333333333
)
[183] => Array
(
[0] => 24.125
)
)
)
Thanks in advance to those who can help! :)
Note: This is just a sample structure of the array. It's possible that the children of 21 and 23 can have another children, meaning, another nodes. Example:
[65] => Array
(
[0] => 44.125
[x] => Array
(
[0]=> 121.11
)
)
I believe a recursive function is needed on this one.
try this, I think this is what you want
$count1 = 0;$sum=0;
$count2 = 0;$sum2=0;
foreach ($array as $key3 => $value3)
{
if($key3 == "21")
{
foreach ($value3 as $key => $value)
{
if (strpos($key, '0') === 0) {
$count1++;$sum=$sum+$value;
}
if(is_array($value))
{
foreach($value as $key2=>$value2)
{
if(strpos($key2,'0') === 0)
{
$count1++ ;$sum=$sum+$value2;
}
}
}
}
}
if($key3 == "23")
{
foreach ($value3 as $key => $value)
{
if (strpos($key, '0') === 0) {
$count2++;$sum2=$sum2+$value;
}
if(is_array($value))
{
foreach($value as $key2=>$value2)
{
if(strpos($key2,'0') === 0)
{
$count2++; $sum2=$sum2+$value2;
}
}
}
}
}
}
$array[21][0] = ($sum/$count1);
$array[23][0] = ($sum2/$count2);
Demo
I have array like this
Array ([0] => Array ( [user_id] => 21 [email] => momod#modara.com [brand] => Array ( [0] => GOFUEL_W [1] => GOFUEL_USD_W ) ) [1] => Array ( [user_id] => 22 [email] => hemisphere#modara.com [brand] => Array ( [0] => GOFUEL_W ) ) [2] => Array ( [user_id] => 23 [email] => madoka#modara.com [brand] => Array ( [0] => GOFUEL_W [1] => GOFUEL_USD_W [2] => GOFUEL_BGD_W ) ) )
i want to locate user_id 22 and put this value "GO_FUEL_SGD_W" on brand, what should i do, so the view of array will look like this
Array ([0] => Array ( [user_id] => 21 [email] => momod#modara.com [brand] => Array ( [0] => GOFUEL_W [1] => GOFUEL_USD_W ) ) [1] => Array ( [user_id] => 22 [email] => hemisphere#modara.com [brand] => Array ( [0] => GOFUEL_W => [1] =>GO_FUEL_SGD_W ) ) [2] => Array ( [user_id] => 23 [email] => madoka#modara.com [brand] => Array ( [0] => GOFUEL_W [1] => GOFUEL_USD_W [2] => GOFUEL_BGD_W ) ) )
Just use loop:
foreach($array as &$item)
{
if(array_key_exists('user_id', $item) &&
$item['user_id']==22 &&
array_key_exists('brand', $item) &&
!in_array('GO_FUEL_SGD_W', $item['brand']))
{
$item['brand'][] = 'GO_FUEL_SGD_W';
}
}
A simple foreach loop will do the job:
foreach($myarray AS &$subarray) {
if($subarray['user_id'] == 22) {
$subarray['brand'][] = "GO_FUEL_SGD_W";
break;
}
}
Working example: http://3v4l.org/8aQMj
You will need to iterate over the array and look for the element you're searching for.
foreach ($array as &$element) {
if ($element['user_id'] != 22)
continue;
$element['brand'][] = "GO_FUEL_SGD_W";
break;
}
With continue; all elements will be skipped, who have $element['user_id'] != 22 (and so none of the code after the continue; will be applied to them!).
Also it will end the loop once the requested element is reached and modified, thanks to break;.
$array= //your array;
foreach($array as $x){
if($x['user_id']=='22'){
$x['brand'][]='GO_FUEL_SGD_W';
break;
}
}
how can i count an element if it appears more than once in the same array?
I already tried with array_count_values, but it did not work, is it beacuse i got more than one key and value in my array?
This is my output from my array (restlist)
Array (
[0] => Array ( [restaurant_id] => 47523 [title] => cafe blabla)
[1] => Array ( [restaurant_id] => 32144 [title] => test5)
[2] => Array ( [restaurant_id] => 42154 [title] => blabla2 )
[3] => Array ( [restaurant_id] => 32144 [title] => test5)
[4] => Array ( [restaurant_id] => 42154 [title] => blabla2 )
)
I want it to count how many times the same element appears in my array and then add the counted value to my newly created 'key' called hits in the same array.
Array (
[0] => Array ( [restaurant_id] => 47523 [title] => cafe blabla [hits] => 1)
[1] => Array ( [restaurant_id] => 32144 [title] => test5 [hits] => 2)
[2] => Array ( [restaurant_id] => 42154 [title] => blabla2 [hits] => 2)
)
This is how i tried to do what i wanted.
foreach ($cooltransactions as $key)
{
$tempArrayOverRestaurants[]= $key['restaurant_id'];
}
$wordsRestaruants = array_count_values($tempArrayOverRestaurants);
arsort($wordsRestaruants);
foreach ($wordsRestaruants as $key1 => $value1)
{
$temprestaurantswithhits[] = array(
'restaurant_id' => $key1,
'hits' => $value1);
}
foreach ($restlistas $key)
{
foreach ($temprestaurantswithhits as $key1)
{
if($key['restaurant_id'] === $key1['restaurant_id'])
{
$nyspisestedsliste[] = array(
'restaurant_id' => $key['restaurant_id'],
'title' => $key['title'],
'hits' => $key1['hits']);
}
}
}
I know this is probably a noob way to do what i want but i am still new at php..I hope you can help
Just try with associative array:
$input = array( /* your input data*/ );
$output = array();
foreach ( $input as $item ) {
$id = $item['restaurant_id'];
if ( !isset($output[$id]) ) {
$output[$id] = $item;
$output[$id]['hits'] = 1;
} else {
$output[$id]['hits']++;
}
}
And if you want to reset keys, do:
$outputWithoutKeys = array_values($output);