hi i have the follwing array structure
Array
(
[_id] => MongoId Object
(
[$id] => 538978ce8ead0ec1048b456c
)
[cartId] => 98374319ff71dbc3a84b842b7a443cf7
[products] => Array
(
[0] => Array
(
[productId] => 100343
[quantity] => 17
[name] => a
)
[1] => Array
(
[productId] => 100344
[quantity] => 3
[name] => ab
)
[2] => Array
(
[productId] => 100345
[quantity] => 1
[name] => abc
)
)
And i'm having problems to increment the quantity of the products based on the productId
I now use the position but i have no reference on id
$oCartsCollection->update(array('cartId'=>'98374319ff71dbc3a84b842b7a443cf7'), array('$inc' => array('products.0.quantity'=>1)));
What you need to do is add to your query to select and element from your array and then use the positional $ operator in order to match that position:
$oCartsCollection->update(
array(
'cartId'=>'98374319ff71dbc3a84b842b7a443cf7',
'products.productId' => 100343
),
array('$inc' => array('products.$.quantity'=>1)));
The "dot" notation method is fine for accessing the productId element in this case. For multiple fields to match use $elemMatch instead
$oCartsCollection->update(
array(
'cartId'=>'98374319ff71dbc3a84b842b7a443cf7',
'products' => array(
'$elemMatch' => array(
'productId' => 100343,
'name' => 'a'
)
)
),
array('$inc' => array('products.$.quantity'=>1)));
Related
i can't believe that i can't find a solution to this seemingly simple problem, and i tried everything.
i have two multi arrays:
the first one:
Array
(
[3] => Array
(
[1] => Array
(
[approved] => 1
[id_note] => 1
[surname] => Rawson
)
[2] => Array
(
[approved] =>
[id_note] => 18
[surname] => Vallejo
)
)
[4] => Array
(
[1] => Array
(
[school_id] => 1
)
[2] => Array
(
[available] => 1
)
)
)
the second one has the exact same structure, but with new data:
Array
(
[3] => Array
(
[1] => Array
(
[final_approved] => 1
[final_id_note] => 1
)
[2] => Array
(
[final_approved] =>
[final_id_note] => 19
)
)
)
what i need mergin both multi-arrays is this result:
Array
(
[3] => Array
(
[1] => Array
(
[approved] => 1
[id_note] => 1
[surname] => Rawson
[final_approved] => 1
[final_id_note] => 1
)
[2] => Array
(
[approved] =>
[id_note] => 18
[surname] => Vallejo
[final_approved] =>
[final_id_note] => 19
)
)
[4] => Array
(
[1] => Array
(
[school_id] => 1
)
[2] => Array
(
[available] => 1
)
)
)
but i can't get this result with any common php function:
array_merge:
Array
(
[0] => Array
(
[1] => Array
(
[approved] => 1
[id_note] => 1
[surname] => Rawson
)
[2] => Array
(
[approved] =>
[id_note] => 18
[surname] => Vallejo
)
)
[1] => Array
(
[1] => Array
(
[school_id] => 1
)
[2] => Array
(
[available] => 1
)
)
[2] => Array
(
[1] => Array
(
[final_approved] => 1
[final_id_note] => 1
)
[2] => Array
(
[final_approved] =>
[final_id_note] => 19
)
)
)
it replaces with new indexes.
array_push:
Array
(
[3] => Array
(
[1] => Array
(
[approved] => 1
[id_note] => 1
[surname] => Rawson
)
[2] => Array
(
[approved] =>
[id_note] => 18
[surname] => Vallejo
)
)
[4] => Array
(
[1] => Array
(
[school_id] => 1
)
[2] => Array
(
[available] => 1
)
)
[5] => Array
(
[3] => Array
(
[1] => Array
(
[final_approved] => 1
[final_id_note] => 1
)
[2] => Array
(
[final_approved] =>
[final_id_note] => 19
)
)
)
)
it literally pushes in with the second array with new indexes, which is correct of course lol
i guess that the answer is pretty simple, but i already googled and try everything that my newbie ability can.
can anyone give me some advice?
thanks!
There are recursive array functions in PHP. array_merge_recursive, despite the promising name, will not work here, as it will reindex the numeric keys and add overlapping the data to the end.
However, there is array_replace_recursive that does exactly what you want when you have a multidimensional array with significant keys. Here's your data (in a usable format!):
// The base data:
$a_one = [
3 => [
1 => [
'approved' => 1,
'id_note' => 1,
'surname' => 'Rawson',
],
2 => [
'approved' => 0,
'id_note' => 18,
'surname' => 'Vallejo',
],
],
4 => [
1 => [
'school_id' => 1,
],
2 => [
'available' => 1,
],
],
];
// Data to be added by matching keys:
$a_two = [
3 => [
1 => [
'final_approved' => 1,
'final_id_note' => 1,
],
2 => [
'final_approved' => 0,
'final_id_note' => 19,
],
],
];
Then let's mash them together:
$merged = array_replace_recursive($a_one, $a_two);
This results in the following "merged" array:
[
3 => [
1 => [
'approved' => 1,
'id_note' => 1,
'surname' => 'Rawson',
'final_approved' => 1,
'final_id_note' => 1,
],
2 => [
'approved' => 0,
'id_note' => 18,
'surname' => 'Vallejo',
'final_approved' => 0,
'final_id_note' => 19,
],
],
4 => [
1 => [
'school_id' => 1,
],
2 => [
'available' => 1,
],
],
]
In summary, the way this function behaves (from the manual, numbering added):
If a key from the first array exists in the second array, its value will be replaced by the value from the second array.
If the key exists in the second array, and not the first, it will be created in the first array.
If a key only exists in the first array, it will be left as is.
Or in a more compact statement:
key: scalar EXISTS in A, B => REPLACE from B to A
key: scalar EXISTS in B => CREATE in A
key: scalar EXISTS in A => LEAVE in A
Again, the manual says:
When the value in the first array is scalar, it will be replaced by the value in the second array, may it be scalar or array. When the value in the first array and the second array are both arrays, array_replace_recursive() will replace their respective value recursively.
What's important to note here is that array members with matching keys, that are arrays, will not be "replaced" in full. The "replacement" only applies to the final scalar values or "leaves" of the array (per the logic above). The arrays will be "merged", ie. non-matching keys with scalar values will be combined within each "final array" (or "leafy array" for lack of a better term).
N.B. If you're using this function to "merge" more complex arrays, you'll want to double-check that the outcome matches your expectations. I can't remember off the top of my head all the "quirks" that exist in using this function, but I assure you they are there... don't assume that it will create a seamless union of any and all datasets you may throw at it.
I have a Array list as below, how to split them into equal parts, sort equal parts by id, and merge equal parts in a id using PHP?
Array
(
[0] => Array
(
[id] => 121
[owner] => xa
[name] => xjs
)
[1] => Array
(
[id] => 139
[owner] => xa
[name] => xjs
)
[2] => Array
(
[id] => 1456
[owner] => xv
[name] => bjs
)
[3] => Array
(
[id] => 1896
[owner] => xb
[name] => bjs
)
[4] => Array
(
[id] => 1963
[owner] => xb
[name] => bjs
)
)
Supposed I would like to split them into 2 equal items,
Split them firstly, and the smallest id should be in a equal part at first, they should be like this:
Array
(
[0] => Array
(
[id] => 121
[owner] => xa
[name] => xjs
)
[1] => Array
(
[id] => 139
[owner] => xa
[name] => xjs
)
)
Array
(
[0] => Array
(
[id] => 1456
[owner] => xv
[name] => bjs
)
[1] => Array
(
[id] => 1896
[owner] => xb
[name] => bjs
)
)
Array
(
[0] => Array
(
[id] => 1963
[owner] => xb
[name] => bjs
)
)
my sample code is 5 items, and if 6 items, it should be [1,2],[3,4],[5,6], how many items or parts are not sure, but i should be 2 equal pieces.
Merge them secondly(This is our logic of our project, if you don't know what I am talking about, please ignore the merge question, I only need to know how to split them):
[121, 139] => merge into 139,
[1456, 1896] => merge into 1896,
new list: [139, 1896] => merge into 1896,
and the final list [1896, 1963] merge into the final id 1963
Sounds like you wanted something like this:
$array = [
[
'id' => 121,
'owner' => 'xa',
'name' => 'xjs',
],
[
'id' => 139,
'owner' => 'xa',
'name' => 'xjs',
],
[
'id' => 1456,
'owner' => 'xv',
'name' => 'bjs',
],
[
'id' => 1896,
'owner' => 'xb',
'name' => 'bjs',
],
[
'id' => 1963,
'owner' => 'xb',
'name' => 'bjs',
]
];
// custom function to compare which ID is greater
function customCompare($a, $b)
{
if ($a['id'] === $b['id']) {
return 0;
}
return ($a['id'] < $b['id']) ? -1 : 1;
}
// sort the whole array
usort($array, "customCompare");
// print the whole array as pairs,
// if there is an unpair number
// the last one will be a single member
print_r(array_chunk($array, 2));
I have a question about this:
I have two array, one is static, and one can be updated by the user...
I would like to check for every id from the static array if exist the id to the other array, and if exsist, do something, if doesn't exist (when finish to check) pass to other ID etc...
now, the arrays are these:
user array (the user unlock 2 achievement):
Array (
[0] => Array (
[data] => Array (
[importance] => 0
[achievement] => Array (
[id] => 644081262362202
[title] => Achievement 2
[type] => game.achievement
[url] => http://www.***.com/achievements/achievement2.html
)
)
[id] => 104693166566570
)
[1] => Array (
[data] => Array (
[importance] => 0
[achievement] => Array (
[id] => 968802826528055
[title] => Achievement 1
[type] => game.achievement
[url] => http://www.***.com/achievements/achievement1.html
)
)
[id] => 104023386633548
)
)
the static Array (have 6 achievement saved):
Array (
[0] => Array (
[data] => Array (
[points] => 50
)
[description] => you unlock the achievement2
[title] => Achievement 2
[id] => 644081262362202
)
[1] => Array (
[data] => Array (
[points] => 50
)
[description] => you unlock the achievement3
[title] => Achievement 3
[id] => 912599152147444
)
[2] => Array (
[data] => Array (
[points] => 50
)
[description] => you unlock the achievement5
[title] => Achievement 5
[id] => 913757345379232
)
[3] => Array (
[data] => Array (
[points] => 50
)
[description] => you unlock the achievement6
[title] => Achievement 6
[id] => 921989084564878
)
[4] => Array (
[data] => Array (
[points] => 50
)
[description] => you unlock the achievement1
[title] => Achievement 1
[id] => 968802826528055
)
[5] => Array (
[data] => Array (
[points] => 50
)
[description] => you unlock the achievement4
[title] => Achievement 4
[id] => 1149671038394021
)
)
now, I use this script to echo the final output like the picture (results is the static array):
if (empty($results)) {
//echo 'noAchievement for the app';
} else {
foreach ($results as $result) {
$totalAchievementsApp .= ' [["' . "0" .'"],["'.$result[id] .'"],["'. $result[title] .'"],["'. $result[data][points]."]] ";
}
}
now, How I can do to check inside the this script? I know I have to add another if inside the else to check if the ID is = to other ID, but I don't know how, I'm a little bit confused... I would like to check if the id of the static array exist in the other array, and if exsist, do this:
**$totalAchievementsApp .= ' [["' . "1" .'"],["'.$result[id] .'"],["'. $result[title] .'"],["'. $result[data][points]."]] ";**
Thank you very much :)
If I understand correctly, you want to indicate for each entry in the static array whether its ID exists in the user array.
You can use array_column to generate an array of all IDs in the user array. Then use in_array to check if each static ID exists in that array. Set a value to 1 if its found and 0 if its not found.
For the sake of example, I've generated a new final output array. But you could just add the "found" value to each entry of the the static array.
<?php
$static=array(
array('point'=>50,'title'=>'TITLE 1','id'=>54632),
array('point'=>50,'title'=>'TITLE 2','id'=>54344),
array('point'=>50,'title'=>'TITLE 3','id'=>34225),
array('point'=>50,'title'=>'TITLE 4','id'=>2323245),
array('point'=>50,'title'=>'TITLE 5','id'=>23872445),
);
$user=array(
array('id'=>2323245,'title'=>'TITLE 1','point'=>50),
array('id'=>54344,'title'=>'TITLE 2','point'=>50),
array('id'=>34225,'title'=>'TITLE 3','point'=>50)
);
$final=array();
foreach ($static as $entry) {
$final[]=array(
'found'=>in_array($entry['id'],array_column($user,'id'))?1:0,
'id'=>$entry['id'],
'title'=>$entry['title'],
'point'=>$entry['point']
);
}
echo"<pre>".print_r($final,true)."</pre>";
With your data, the output is:
Array
(
[0] => Array
(
[found] => 0
[id] => 54632
[title] => TITLE 1
[point] => 50
)
[1] => Array
(
[found] => 1
[id] => 54344
[title] => TITLE 2
[point] => 50
)
[2] => Array
(
[found] => 1
[id] => 34225
[title] => TITLE 3
[point] => 50
)
[3] => Array
(
[found] => 1
[id] => 2323245
[title] => TITLE 4
[point] => 50
)
[4] => Array
(
[found] => 0
[id] => 23872445
[title] => TITLE 5
[point] => 50
)
)
EDIT
Given the more complex structure of your actual arrays, I nested several array_column functions to access the deeper "data > achievement > id" keys in your user array:
$user_achvmts=array_column(array_column(array_column($user,'data'),'achievement'),'id');
See the example below:
// initialize the "static" and "user" arrays
$static=array (
0 => array(
'data' => array(
'points' => 50
),
'description' => 'you unlock the achievement2',
'title' => 'Achievement 2',
'id' => 644081262362202
),
1 => array(
'data' => array(
'points' => 50
),
'description' => 'you unlock the achievement3',
'title' => 'Achievement 3',
'id' => 912599152147444
),
2 => array(
'data' => array(
'points' => 50
),
'description' => 'you unlock the achievement5',
'title' => 'Achievement 5',
'id' => 913757345379232
),
3 => array(
'data' => array(
'points' => 50
),
'description' => 'you unlock the achievement6',
'title' => 'Achievement 6',
'id' => 921989084564878
),
4 => array(
'data' => array(
'points' => 50
),
'description' => 'you unlock the achievement1',
'title' => 'Achievement 1',
'id' => 968802826528055
),
5 => array(
'data' => array(
'points' => 50
),
'description' => 'you unlock the achievement4',
'title' => 'Achievement 4',
'id' => 1149671038394021
)
);
$user=array(
0=>array(
'data' => array(
'importance' => 0,
'achievement' => array (
'id' => 644081262362202,
'title' => 'Achievement 2',
'type' => 'game.achievement',
'url' => 'http://www.***.com/achievements/achievement2.html'
)
),
'id' => 104693166566570
),
1 => array (
'data' => array (
'importance' => 0,
'achievement' => array (
'id' => 968802826528055,
'title' => 'Achievement 1',
'type' => 'game.achievement',
'url' => 'http://www.***.com/achievements/achievement1.html'
)
),
'id' => 104023386633548
)
);
// build array of user achievement IDs
$user_achvmts=array_column(array_column(array_column($user,'data'),'achievement'),'id');
// generate final array, with "found" values
$final=array();
foreach ($static as $entry) {
$final[]=array(
'found'=>in_array($entry['id'],$user_achvmts)?1:0,
'id'=>$entry['id'],
'title'=>$entry['title'],
'description'=>$entry['description'],
'points'=>$entry['data']['points']
);
}
echo"<pre>".print_r($final,true)."</pre>";
The result is:
Array
(
[0] => Array
(
[found] => 1
[id] => 644081262362202
[title] => Achievement 2
[description] => you unlock the achievement2
[points] => 50
)
[1] => Array
(
[found] => 0
[id] => 912599152147444
[title] => Achievement 3
[description] => you unlock the achievement3
[points] => 50
)
[2] => Array
(
[found] => 0
[id] => 913757345379232
[title] => Achievement 5
[description] => you unlock the achievement5
[points] => 50
)
[3] => Array
(
[found] => 0
[id] => 921989084564878
[title] => Achievement 6
[description] => you unlock the achievement6
[points] => 50
)
[4] => Array
(
[found] => 1
[id] => 968802826528055
[title] => Achievement 1
[description] => you unlock the achievement1
[points] => 50
)
[5] => Array
(
[found] => 0
[id] => 1149671038394021
[title] => Achievement 4
[description] => you unlock the achievement4
[points] => 50
)
)
Note that array_column is only available in PHP >= 5.5.0. For older versions, see the Recommended userland implementation for PHP lower than 5.5.
As an alternative to array_column, you could use array_map to build an array of the user IDs:
$user_achvmts = array_map( function($v) {return $v['data']['achievement']['id'];}, $user);
Or even just iterate through the user array:
$user_achvmts=[];
foreach ($user as $v) { $user_achvmts[]=$v['data']['achievement']['id']; }
I have a script that loops through a bunch of data collected from database tables. I've read other similar posts on StackOverflow about merging duplicate array keys, but none of them seem to work for me. Using the code below, I'm building all of the compiled data into an array:
$sql = 'SELECT * FROM '.$qstTable.' WHERE '.$type.'_qst_id = '.$answer['answer_qst'];
$result = $db->sql_query($sql);
$q = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$sql = 'SELECT * FROM '.$catTable.' WHERE '.$type.'_cat_clean = "'.$q[$type.'_qst_cat'].'"';
$result = $db->sql_query($sql);
$cat = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$daField = $cat[$type.'_cat_name'];
if(count($allQsts)){
if(array_key_exists($daField, $allQsts)){
$daData = array(
'question' => array(
'id' => $q[$type.'_qst_id'],
'qst' => $q[$type.'_qst_qst'],
),
'answer' => array(
'id' => $answer['answer_id'],
'type' => $answer['answer_input'],
'content' => $answer['answer_content'],
'q_type' => $type,
)
);
array_push($allQsts[$daField], $daData);
}else{
$allQsts[$cat[$type.'_cat_name']][] = array(
'question' => array(
'id' => $q[$type.'_qst_id'],
'qst' => $q[$type.'_qst_qst'],
),
'answer' => array(
'id' => $answer['answer_id'],
'type' => $answer['answer_input'],
'content' => $answer['answer_content'],
'q_type' => $type,
)
);
}
}else{
$allQsts[$cat[$type.'_cat_name']][] = array(
'question' => array(
'id' => $q[$type.'_qst_id'],
'qst' => $q[$type.'_qst_qst'],
),
'answer' => array(
'id' => $answer['answer_id'],
'type' => $answer['answer_input'],
'content' => $answer['answer_content'],
'q_type' => $type,
)
);
}
And this is how my array turns out looking when it's all processed:
Array (
[Ancestry] => Array (
[0] => Array (
[question] => Array (
[id] => 1
[qst] => Has your family always lived in this country? Where did your family come from? How did they come here?
)
[answer] => Array (
[id] => 28
[type] => text
[content] => idk
[q_type] => life
)
)
)
)
Array (
[High School] => Array (
[0] => Array (
[question] => Array (
[id] => 158
[qst] => Who were your best friends in high school? Were they the same ones from grade school? Do you still keep in touch with them?
)
[answer] => Array (
[id] => 30
[type] => video
[content] => v-0bd3d270-2f24-0132-cd89-12313914f10b
[q_type] => life
)
)
)
)
Array (
[High School] => Array (
[0] => Array (
[question] => Array (
[id] => 124
[qst] => What year did you start high school? What high school did you go to? Did you like it? Did you ever wish you would've gone to a different high school?
)
[answer] => Array (
[id] => 36
[type] => text
[content] => Started HS in 1987
[q_type] => life
)
)
)
)
Array (
[Young Adult] => Array (
[0] => Array (
[question] => Array (
[id] => 213
[qst] => As a young adult did you stay in the same town as your friends or did you move to a new place and had to make new friends?
)
[answer] => Array (
[id] => 39
[type] => video
[content] => v-7d59df50-3bda-0132-cda7-12313914f10b
[q_type] => life
)
)
)
)
Array (
[Young Adult] => Array (
[0] => Array (
[question] => Array (
[id] => 207
[qst] => After high school - did you go to college, join the miltary, or did you get a job?
)
[answer] => Array (
[id] => 40
[type] => text
[content] => went to college at ASU
[q_type] => life
)
)
)
)
Array (
[Multiple Sclerosis] => Array (
[0] => Array (
[question] => Array (
[id] => 1278
[qst] => Do you know of any potential new drugs or treatments that are in development to treat multiple sclerosis? Are you optomistic?
)
[answer] => Array (
[id] => 33
[type] => text
[content] => vg hjc
[q_type] => pack
)
)
)
)
However, What I would like to do is combine nodes in the array that already exist, like so:
Array (
[Ancestry] => Array (
[0] => Array (
[question] => Array (
[id] => 1
[qst] => Has your family always lived in this country? Where did your family come from? How did they come here?
)
[answer] => Array (
[id] => 28
[type] => text
[content] => idk
[q_type] => life
)
)
)
)
Array (
[High School] => Array (
[0] => Array (
[question] => Array (
[id] => 158
[qst] => Who were your best friends in high school? Were they the same ones from grade school? Do you still keep in touch with them?
)
[answer] => Array (
[id] => 30
[type] => video
[content] => v-0bd3d270-2f24-0132-cd89-12313914f10b
[q_type] => life
)
)
[1] => Array (
[question] => Array (
[id] => 124
[qst] => What year did you start high school? What high school did you go to? Did you like it? Did you ever wish you would've gone to a different high school?
)
[answer] => Array (
[id] => 36
[type] => text
[content] => Started HS in 1987
[q_type] => life
)
)
)
)
Array (
[Young Adult] => Array (
[0] => Array (
[question] => Array (
[id] => 213
[qst] => As a young adult did you stay in the same town as your friends or did you move to a new place and had to make new friends?
)
[answer] => Array (
[id] => 39
[type] => video
[content] => v-7d59df50-3bda-0132-cda7-12313914f10b
[q_type] => life
)
)
[1] => Array (
[question] => Array (
[id] => 207
[qst] => After high school - did you go to college, join the miltary, or did you get a job?
)
[answer] => Array (
[id] => 40
[type] => text
[content] => went to college at ASU
[q_type] => life
)
)
)
)
Array (
[Multiple Sclerosis] => Array (
[0] => Array (
[question] => Array (
[id] => 1278
[qst] => Do you know of any potential new drugs or treatments that are in development to treat multiple sclerosis? Are you optomistic?
)
[answer] => Array (
[id] => 33
[type] => text
[content] => vg hjc
[q_type] => pack
)
)
)
)
How can I modify the code above to do this?
EDIT - Updating to include some of the code I've tried to compress the array:
After the full $allQsts array is created, I looped it through this and tested the output, but each entry was duplicated even more.
$sortedIt = array();
foreach($allQsts as $m => $n){
if(!isset($sortedIt[$m])){
$sortedIt[$m] = array();
}
$sortedIt[$m] = $n;
}
I've also been playing around with array_merge_recursive but have yet to get anywhere close.
Assuming this is run in a loop and $allQsts points to the same array each time, you can simplify the code drastically:
$daField = $cat[$type.'_cat_name'];
$daData = array(
'question' => array(
'id' => $q[$type.'_qst_id'],
'qst' => $q[$type.'_qst_qst'],
),
'answer' => array(
'id' => $answer['answer_id'],
'type' => $answer['answer_input'],
'content' => $answer['answer_content'],
'q_type' => $type,
)
);
if (array_key_exists($daField, $allQsts)) {
$allQsts[$daField][] = $daData;
} else {
$allQsts[$daField] = array($daData);
}
This by itself should be enough to get the desired data structure.
I am using the following cakephp query to retrieve data from mysql:
$tops = $this->PageBanner->find('all', array(
'conditions' => array(
'PageBanner.status' => 1
),
'fields' => array(
'PageBanner.page_url',
'PageBanner.image',
'PageBanner.logo',
'PageBanner.logo_text',
'PageBanner.content'
)
));
This query returns me the following results:
[0] => Array
(
[PageBanner] => Array
(
[page_url] => index
[image] => home_banner.png
[logo] => home_logo.png
[logo_text] => abc
[content] => abc.
)
)
[1] => Array
(
[PageBanner] => Array
(
[page_url] => write_review
[image] => kids2.png
[logo] => home_logo.png
[logo_text] => abc
[content] => abc.
)
)
But I want the data to be returned in the following format:
[index] => Array
(
[page_url] => index
[image] => home_banner.png
[logo] => home_logo.png
[logo_text] => abc
[content] => abc.
)
[write_review] => Array
(
[page_url] => write_review
[image] => kids2.png
[logo] => home_logo.png
[logo_text] => abc
[content] => abc.
)
I need page_url field content in place of Array index (e.i. 0, 1). Is that possible to get data in this format or I need to manually configure the arrays?
$result = Set::combine($tops, '{n}.PageBanner.page_url', '{n}.PageBanner');
pr($result);