I am taking information from a JSON feed, and creating a JSON feed that I can use more easily across more devices. The problem I am having is when creating the new array in PHP for the JSON feed, I need to use a foreach loop. Here is my code for the foreach loop:
$obj = json_decode($json);
$json_decode = objectToArray($obj);
$special_number = '0';
$special_number2 = '0';
foreach($json_decode AS $r) {
$info = explode('.', $json_decode[$special_number]['Id']);
$newarray = array( $special_number => array( 'client' => $info['4'], 'placementID' => $info['2'], 'creativeID' => $info['3'], 'dimensions' => $info['3'], 'impressions' => $json_decode[$special_number]['Impressions'], 'bxd' => $json_decode[$special_number]['BXD'], 'viewable_impressions' => $json_decode[$special_number]['ViewableImpressions'], 'exposure' => $json_decode[$special_number]['Exposure'], 'viewability_rate' => $json_decode[$special_number]['ViewableRate'], 'clicks' => $json_decode[$special_number]['AdClicks'], 'mouse_overs' => $json_decode[$special_number]['AdMouseOvers'] ));
$fullarray = array_merge($newarray);
$special_number++;
}
I am basically taking their arrays, reordering the info and getting only the data I need, and creating a new array with it, called $fullarray. Each of the sub arrays I am making are generated each time, is it due to me running a foreach it is destorying the old $fullarray, and creating a new one? It is giving me the following:
Array
(
[0] => Array
(
[client] =>
[placementID] => 3
[creativeID] => 4
[dimensions] => 4
[impressions] => 1
[bxd] => 0
[viewable_impressions] => 0
[exposure] => 0
[viewability_rate] => 0
[clicks] => 1
[mouse_overs] => 1
)
)
I have searched for this, but I can not find it, other threads are about combining different keys and values, I am having to create subarrays to keep the keys the same, and have different values (this is what I want, yes.)
Any help will be appreciated! :)
This should do it:
$fullarray = array()
foreach(...)
{
...
$fullarray = array_merge($fullarray,$newarray);
}
The merge function can take more arrays parameters to be merged, in your case you did not merged the contents of fullarray to the new array, instead you overwrite it.
You may also need to declare full array before foreach
Related
I've researched topics similar to this but not exactly what I'm looking to do.
I have a multidimensional array like the following.
[code] => BILL
[assets] => Array
(
[en] => Array
(
[datatype] => My Assets
[data] => Array
(
[Corporate Equity] => 41
[Global Equity] => 24
[Fixed Income – Government] => 22
[Fixed Income – Corporate] => 8.1
[Other] => 3.57
)
)
)
I'd like to remove the first inner array, but preserve the values. Shift them up one level in the array so that it looks like this.
[code] => BILL
[assets] => Array
(
[datatype] => My Assets
[data] => Array
(
[Corporate Equity] => 41
[Global Equity] => 24
[Fixed Income – Government] => 22
[Fixed Income – Corporate] => 8.1
[Other] => 3.57
)
)
This is just the beginning of the array, there are other instances of the same key [en] at the same level.
I've tried unset, array_shift and others but I need to keep the contents of [en], just shift them up one level in the array.
You can use array_map which returns an array which contains all elements of the previous array after applying the function.
In this case it will simply take the array at index en and add it's contents to the new array.
http://php.net/manual/en/function.array-map.php
$arr = array('assets' => array(
'en' => array(
'datatype' => 'My Assets',
'data' => array(
'Corporate Equity' => 41,
'Global Equity' => 24,
'Fixed Income – Government' => 22,
'Fixed Income – Corporate' => 8.1,
'Other' => 3.57
)
)
));
$new_arr = array_map(function ($e) {
return $e['en'];
}, $arr);
A simple solution that assumes the key to always be en and the subkeys to always be (only) datatype and data:
$assets['datatype'] = $assets['en']['datatype'];
$assets['data'] = $assets['en']['data'];
unset( $assets['en'] );
This code could be problematic for you in the future if that array structure ever changes (it lacks extensibility), but it gets you what you want given the information you have provided.
array_shift is the opposite of array_pop. Used in stack/queue like structures for removing the fist element http://php.net/manual/en/function.array-shift.php
What you want to do is flatten the array. But if you want to keep all the other sub-arrays as you mentioned, you might look up array_merge.
I faced the same scenario after using reader to read xml file, the returned array was having inserted 0 key array in each level like the following one:
'config' =>
0 =>
'products' =>
0 =>
'media' =>
.
.
.
so I built a small function to get rid of a specific key and shift up its child's in a two dimensions array, in my case the key was 0. hopping this would help somebody also.
public function clearMaps(&$maps, $readerMaps, $omittedKey)
{
if (is_array($readerMaps)) {
foreach ($readerMaps as $key => $map) {
if ($key !== $omittedKey) {
$maps[$key] = [];
$this->clearMaps($maps[$key], $readerMaps[$key], $omittedKey);
} else {
$this->clearMaps($maps, $readerMaps[$key], $omittedKey);
}
}
} else {
$maps = $readerMaps;
}
}
// $maps: cleaned array, will start as empty array
// $readerMaps: array needs to be cleaned
// $omittedKey: array key to git rid of.
// first call is clearMaps([], $readerMaps, 0);
(
[1] => Array
(
[rules_properties_id] => 1
[operator] => >=
[value] => 2
[function] => NumOrdersPlaced
[rules_properties_params] => Array
(
[num_days] => 30
[customer_id] => 5
)
)
[2] => Array
(
[rules_properties_id] => 1
[operator] => >=
[value] => 5
[function] => NumOrdersPlaced
[rules_properties_params] => Array
(
[num_days] => 90
[customer_id] => 5
)
)
[3] => Array
(
[rules_properties_id] => 2
[operator] => >
[value] => 365
[function] => CustAcctAge
[rules_properties_params] => Array
(
[customer_id] => 5
)
)
)
That's the print_r of an array that I'm getting back from my database. I need to find the index number of the sub-array that contains the function called NumOrdersPlaced (the expected result would be 2.) Is the only way to do this by looping through the array and subarrays and comparing (as in this answer)? Or is there a more efficient, elegant (i.e. one-liner) function available that I don't know about?
No, there is no one liner for searching multidimensional arrays in PHP, expect you'll write a function for it yourself and use it as one liner :)
Approaches would be:
Change the data structure to somewhat that is good for search operations. eg xml with xpath
When creating the array from your question, create another array which indexes are the function names, and which values are pointers to the sub arrays of the original array
Use the database for that operations. It's optimized for it
...
When searching for the 'right' way you'll have to find a compromise between performance of search, insert, update, remove operations, memory consumption and ease of usage.
As you asked for a PHP solution, here comes an example how I would do it in PHP using and additional index array: (approach 2. from the list above)
// we need two arrays now:
$data = array();
$index = array();
// imagine you loop through database query results
foreach($db_result as $record) {
// create a copy of $record as the address
// of record will contain the last(!) element agter foreach
$item = $record;
// store pointers to that array in data and index
$data []= &$item;
$index[$item->function] = &$item;
}
// here is your one liner
$found = isset($index['NumOrdersPlaced']) ? $index['NumOrdersPlaced'] : NULL;
// another index seach:
$found = isset($index['CustAcctAge']) ? $index['CustAcctAge'] : NULL;
// note there is no additonal loop. The cost is the
// additional memory for $index
I am trying to build a new array from simpleXmlElement. I am getting the information I want, just not in the right hierarchy.
$xmlNew1 = new SimpleXMLElement($responseNew1);
$test = array();
foreach ($xmlNew1->children() as $newChild){
$classIden[] = (string)$xmlNew1->class['id'];
$item[] = (string)$xmlNew1->code;
$family[] = (string)$xmlNew1->family;
for($i=0, $count = count($classIden); $i < $count; $i++) {
$test[$item[$i]][$family[$i]]= $classIden[$i];
}
}
print_r($test);
this gives me:
Array
(
[9522] => Array
(
[Mens Hats] => 44
)
[9522-NC-NO SIZE] => Array
(
[Mens Hats] => 44
)
[B287CSQU] => Array
(
[Boys] => 1
)
but I want
Array
(
[9522] => Array
(
[family] => Mens Hats
[classId] => 44
)
Any suggestion? Thanks!
This should probably do it (to replace the main loop contents):
$id = (string)$newChild->class['id'];
$code = (string)$newChild->code;
$family = (string)$newChild->family;
$items[$code] = array(
'family' => $family,
'classId' => $id,
);
Edit
Forgot to use $newChild instead of $xmlNew1.
I don't know your hierarchy because I do not know much about the HTML. You've hidden the structure. However, you should probably build the array in the format you look for directly.
Let us try to make that less complicated. Let's say you have a variable that would contain all the children. So you can pull apart the iteration and loading these children. Loading:
$xmlNew1 = new SimpleXMLElement($responseNew1);
$newChildren = $xmlNew1->children();
I can not say you if $xmlNew1->children() is sufficient to get you all the xml elements you are looking for, but let's just assume so.
Next part is about the iteration. As written you should build the $test array while you iterate over the children - as you partly already did:
$test = array();
foreach ($newChildren as $newChild) {
...
}
Missing part now is to create your structure in $test:
Array(
[9522] => Array(
[family] => Mens Hats
[classId] => 44
)
I like the suggestion #Jack gives here to first assign the values you want to extract to variables of their own and then create the entry.
$newItem = array(
'family' => $family,
'classId' => $id,
);
$test[$code] = $newItem;
Naturally you have to place that into the iteration. When the iteration is done, the $test array should have the format you're looking for.
I hope this is helpful.
I am trying to edit a plugin that is fetching a multidimensional array, then breaking it out into a foreach statement and doing stuff with the resulting data.
What I am trying to do is edit the array before it gets to the foreach statement. I want to look and see if there is a key/value combination that exists, and if it does remove that entire subarray, then reform the array and pass it to a new variable.
The current variable
$arrayslides
returns several subarrays that look like something like this (I remove unimportant variables for the sake of briefness):
Array (
[0] => Array (
[slide_active] => 1
)
[1] => Array (
[slide_active] => 0
)
)
What I want to do is look and see if one of these subarrays contains the key slide_active with a value of 0. If it contains a value of zero, I want to dump the whole subarray altogether, then reform the multidimensional array back into the variable
$arrayslides
I have tried a few array functions but have not had any luck. Any suggestions?
$arrayslides = array(0 => array ( 'slide_active' => 1, 'other_data' => "Mark" ),
1 => array ( 'slide_active' => 0, 'other_data' => "ABCDE" ),
2 => array ( 'slide_active' => 1, 'other_data' => "Baker" ),
3 => array ( 'slide_active' => 0, 'other_data' => "FGHIJ" ),
);
$matches = array_filter($arrayslides, function($item) { return $item['slide_active'] == 1; } );
var_dump($matches);
PHP >= 5.3.0
I know its not so efficient but still
foreach ($arraySlides as $key => $value)
{
if(in_array('0', array_values($value))
unset($arraySlides[$key]);
}
I am pulling some data from a mysql table via the following:
$result = mysql_query("SELECT characters_ID, name, borndate, deathdate, marrieddate, ispregnant FROM characters WHERE isfemale='1'",$db);
$femaledata = array();
while ($row_user = mysql_fetch_assoc($result))
$femaledata[] = $row_user;
This gives me an array that looks like this:
Array (
[0] => Array ( [characters_ID] => 2 [name] => Helene [borndate] => 35 [deathdate] => 431 [marrieddate] => 157 [ispregnant] => 0 )
[1] => Array ( [characters_ID] => 4 [name] => Isabelle [borndate] => 161 [deathdate] => [marrieddate] => 303 [ispregnant] => 1 )
[2] => Array ( [characters_ID] => 7 [name] => Helene [borndate] => 326 [deathdate] => [marrieddate] => [ispregnant] => 0 )
[3] => Array ( [characters_ID] => 72 [name] => Faylinn [borndate] => 335 [deathdate] => [marrieddate] => [ispregnant] => 0 )
[4] => Array ( [characters_ID] => 74 [name] => Relina [borndate] => 349 [deathdate] => [marrieddate] => [ispregnant] => 0 )
)
Now I need to remove any characters who have a value for deathdate or ispregnant, and then I need to run some code on the others. For instance I need to grab the borndate value, compare it to the current date to find age, and based partly on age, I need to run code for each to determine if the character has become pregnant on the turn.
Apologies that this seems like a long-reaching question. Multidimensional arrays still seem to confound me.
Edit: (question needs to be more clear)
Can you please suggest the best way that I would either explode or break up the array, and then do conditional modification to the data, or instead how I could remove unneeded data and then do conditional modification to the data.
My ultimate output here would be taking suitable female characters (not dead or pregnant already), and based on their age, giving them a chance at becoming pregnant. If true, I'd throw some code back at the SQL database to update that character.
Thanks!
All the things you need could probably get done with SQL :
Now I need to remove any characters who have a value for deathdate or
ispregnant
Simply add some argument to your WHERE condition :
isPregnant IS NULL AND deathdate IS NULL
For instance I need to grab the borndate value, compare it to the
current date to find age
Depending of your field format the maths could be done in SQL , have look to the DATE function of mysql
Don't underestimate the power of your sql server , 99% of the time it is probably faster than php to work on data set.
Instead if immediately removing some rows from your array, try limiting the data you recieve through SQL.
You can loop through your array like this:
foreach($femaledata as $female)
{
echo $female['name'];
}
do you mean something like this?
$femaledata = array();
while ($row_user = mysql_fetch_assoc($result)) {
$ok = false;
// do you validation for every user
if($ok) array_push($femaledata,$row_user);
}
TJHeuvel gave you the right answer, and you should accept that answer. However, to inform: multidimensional arrays need not confound. Let me see if I can explain.
In PHP, you can put any object at all into an array, including other arrays. So, let's say you have an array that contains other arrays. When you iterate over that array using a looping construct (usually a foreach loop), each iteration of the loop will give you another array; if you want to access the elements of this sub-array, just loop over it. This is called a nested loop. Example:
$r = array(
array(1,2,3),
array(4,5,6),
array(7,8,9)
);
foreach ($r as $cur) {
foreach ($cur as $num) {
echo $num;
}
}
In each iteration of the outer loop, $cur contains an array; the inner loop iterates over contents of this array. This technique allows you to process arrays of any dimension.
However, in your specific case, you don't need to use an inner loop to iterate over your subarrays. You only need to access certain elements of your subarrays by their keys, rather that processing all of them in turn. So, a simple foreach loop will do.