I have the array $conversion[$cohort_check] which is outputting the following:
Array
(
[0] => Array
(
[order_id] => 62056
[order_date] => 21-01
[total] => 5.5
[cumulative] => 0
[order_type] => one_time
)
[1] => Array
(
[order_id] => 52937
[order_date] => 21-02
[total] => 5.5
[cumulative] => 0
[order_type] => one_time
)
[2] => Array
(
[order_id] => 45849
[order_date] => 21-03
[total] => 7.89
[cumulative] => 0
[order_type] => parent
)
[3] => Array
(
[order_id] => 228
[order_date] => 21-10
[total] => 5.23
[cumulative] => 0
[order_type] => parent
)
)
How can I check if the value of order_type is parent exists anywhere within it?
I tried the following but don't think I'm quite hitting the right place.
if(in_array("parent", $conversion[$cohort_check])){
echo "subscribed!";
}
Is it then possible to grab the value of order_date for the first parent order it gets?
you do not need to loop over the array. PHP has the https://www.php.net/array_search, which does exactly what you need:
If you want just one result:
array_search('parent', array_column($array, 'order_type'));
For multiple results
$keys = array_keys(array_column($array, 'order_type'), 'parent');
$x = array(
array(
'order_id' => '62056',
'order_date' => '21-01',
'total' => '5.5',
'cumulative' => '0',
'order_type' => 'one_time'
),
array(
'order_id' => '62056',
'order_date' => '21-01',
'total' => '5.5',
'cumulative' => '0',
'order_type' => 'one_time'
),
array(
'order_id' => '52937',
'order_date' => '21-02',
'total' => '5.5',
'cumulative' => '0',
'order_type' => 'parent'
),
);
simply use foreach loop and then apply your condition on particular key
foreach ($x as $key => $xx) {
if($xx["order_type"] == "parent" ){
echo "Subscribed";
}
}
This will loop the array and echo the order_id that has order_type as parent (Subscribed).
$array = array(
array(
'order_id' => 1589,
'order_type' => 'one_time'
),
array(
'order_id' => 1579,
'order_type' => 'parent'
),
array(
'order_id' => 1289,
'order_type' => 'one_time'
),
array(
'order_id' => 2589,
'order_type' => 'parent'
),
array(
'order_id' => 1584,
'order_type' => 'one_time'
),
array(
'order_id' => 8589,
'order_type' => 'one_time'
),
);
foreach ($array as $value) {
if ($value['order_type'] === 'parent') {
echo 'Order: ' . $value['order_id'] . ': Subscribed' . '<br>';
}
}
// Output
Order: 1579: Subscribed
Order: 2589: Subscribed
EDIT:
There is another answer with array_keys(array_column($array, 'order_type'), 'parent') this indeed works fine but you're still going to have to then process that array to get some meaningful information like the order_id. Assuming that is ultimately what you're wanting (To see what order is subscribed).
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 have three array as bellow :
$one = array (
array (
'supplier_name' => 'SUP1',
'product_code' => 'ITM001',
'product' => 'Book',
'price' => '5500',
),
array (
'supplier_name' => 'SUP1',
'product_code' => 'ITM002',
'product' => 'Pencil',
'price' => '1500',
),
array (
'supplier_name' => 'SUP1',
'product_code' => 'ITM002',
'product' => 'Eraser',
'price' => '1750',
),
)
$two = array (
array (
'supplier_name' => 'SUP2',
'product_code' => 'SP001',
'product' => 'Book',
'price' => '5250',
),
array (
'supplier_name' => 'SUP2',
'product_code' => 'SP002',
'product' => 'Pencil',
'price' => '1550',
),
array (
'supplier_name' => 'SUP2',
'product_code' => 'SP002',
'product' => 'Ruler',
'price' => '2300',
),
)
$three = array (
array (
'supplier_name' => 'SUP3',
'product_code' => 'BRG01',
'product' => 'Book',
'price' => '5250',
),
array (
'supplier_name' => 'SUP3',
'product_code' => 'BRG02',
'product' => 'Ruler',
'price' => '2350',
),
array (
'supplier_name' => 'SUP3',
'product_code' => 'BRG02',
'product' => 'Drawing book',
'price' => '4500',
),
)
I have already merge all above array with array_merge.
$all_array = array (
0 =>
array (
'supplier_name' => 'SUP1',
'product_code' => 'ITM001',
'product' => 'Book',
'price' => '5500',
),
1 =>
array (
'supplier_name' => 'SUP1',
'product_code' => 'ITM002',
'product' => 'Pencil',
'price' => '1500',
),
2 =>
array (
'supplier_name' => 'SUP1',
'product_code' => 'ITM002',
'product' => 'Eraser',
'price' => '1750',
),
3 =>
array (
'supplier_name' => 'SUP2',
'product_code' => 'SP001',
'product' => 'Book',
'price' => '5250',
),
4 =>
array (
'supplier_name' => 'SUP2',
'product_code' => 'SP002',
'product' => 'Pencil',
'price' => '1550',
),
5 =>
array (
'supplier_name' => 'SUP2',
'product_code' => 'SP002',
'product' => 'Ruler',
'price' => '2300',
),
6 =>
array (
'supplier_name' => 'SUP3',
'product_code' => 'BRG01',
'product' => 'Book',
'price' => '5250',
),
7 =>
array (
'supplier_name' => 'SUP3',
'product_code' => 'BRG02',
'product' => 'Ruler',
'price' => '2350',
),
8 =>
array (
'supplier_name' => 'SUP3',
'product_code' => 'BRG02',
'product' => 'Drawing book',
'price' => '4500',
),
)
How can I remove duplicate with higher value and only get lower price of all items.
Array
(
[0] => Array
(
[supplier_name] => SUP2
[product_code] => SP001
[product] => Book
[price] => 5250
)
[1] => Array
(
[supplier_name] => SUP1
[product_code] => ITM002
[product] => Pencil
[price] => 1500
)
[2] => Array
(
[supplier_name] => SUP1
[product_code] => ITM002
[product] => Eraser
[price] => 1750
)
[3] => Array
(
[supplier_name] => SUP2
[product_code] => SP002
[product] => Ruler
[price] => 2300
)
[4] => Array
(
[supplier_name] => SUP3
[product_code] => BRG02
[product] => Drawing book
[price] => 4500
)
)
Please advise. Thank you.
It seems you're using PHP. Although it would be way better and less painful to have your products mapped with a unique named key, here's a way to solve your problem.
Don't use array_merge since it doesn't allow you to use a callback to keep only the cheaper product.
Here is a pseudo-code you could use (rather than untested php I would provide). Adapt it to your source code.
// Everything has a beginning.
array_result = array()
// Browsing array1
For each item of array1
found_item = false
// For each product of array1, seeking for the same product in array2
For each item2 of array2
If areTheSameProduct(item1, item2)
If item1.price < item2.price Then
appendToArray(array_result, item1)
Else
appendToArray(array_result, item2)
End If
found_item = true
// Removing then the product in array2, to let at the end only
// the ones which was't found in array1.
// In PHP, use here unset() to remove an element from the array.
// "key" parameter can be a named index or the classic integer one
unset(array1[key of item2])
Break // No need to continue the loop on array2
End If
End For
// Item not found in array2? We'll keep the one of array1.
If (Not found_item) Then appendToArray(array_result, item1)
End For
// For the remaining values of array_two (which were not in array1)
For each item2 of array2
appendToArray(array_result, item2 )
End For
// Comparator function
Function areTheSameProduct(item1, item2)
return (item1.supplier_name == item2.supplier_name) AND
(item1.product_code == item2.product_code) AND
(item1.product == item2.product)
End Function
I need to Search collection in mongodb having
'food_name' => 'fish'
and
'room_features' =>
array (
0 => 'Shower',
1 => 'Hairdryer',
),
I tried the following code. But the result is not-correct. I think multiple $eq is not allowed (same index in array).
array (
'$and' =>
array (
array (
'food' =>
array (
'$elemMatch' =>
array (
'food_name' =>
array (
'$eq' => 'fish',
),
),
),
),
array (
'room' =>
array (
'$elemMatch' =>
array (
'room_features' =>
array (
'$elemMatch' =>
array (
'$eq' => 'Shower'
'$eq' => 'Hairdryer'
),
),
'roomrate' =>
array (
'$eq' => new MongoInt32(2500),
),
),
),
),
),
)
Here is the document I need to search.
array (
'_id' => new MongoId("59670aca7fafd8342e3c9869"),
'subcat_name' => 'Test',
'place' => '',
'description' => '',
'created_date' => '1499970060',
'created_by' => 'Admin',
'openingtime' => '',
'closingtime' => '',
'hotel_class_id' => '594245f67fafd87e243c986a',
'hotel_type_id' => '594244177fafd884563c9869',
'latitude' => '0',
'longitude' => '0',
'dist_id' => '5911966a7fafd8c83c3c986a',
'cat_id' => '58fb230e7fafd883183c986d',
'featured' => '0',
'visited' => new MongoInt64(5),
'subcat_slug' => 'test-trivandrum-1',
'image' => NULL,
'food' =>
array (
0 =>
array (
'food_id' => '149992634012642164',
'region_id' => '5944ba947fafd883333c9869',
'food_name' => 'fish',
'type' => 'veg',
'rate' => '100',
),
1 =>
array (
'food_id' => '14999366891994980639',
'region_id' => '595c75c17fafd835173c986c',
'food_name' => 'curry',
'type' => 'veg',
'rate' => '1000',
),
),
'room' =>
array (
0 =>
array (
'room_id' => '14999346791721342880',
'roomtype' => 'DELUXE KING ROOM1',
'roomrate' => new MongoInt64(2500),
'image' => 'beach_icon33.png',
'room_features' =>
array (
0 => 'Shower',
1 => 'Hairdryer',
),
),
1 =>
array (
'room_id' => '14999346901389554873',
'roomtype' => 'DELUXE KING ROOM new',
'roomrate' => new MongoInt64(4000),
'image' => 'beach_icon34.png',
'room_features' =>
array (
0 => 'Shower',
1 => 'Bathrobe',
),
),
),
)
Please Give me an alternate way to search multiple item from array.
Thanks in advance.
I think if you want to query list you can add the list in query,
try this
{
"food" : {
"$elemMatch": {
"food_name" : "fish"
}
},
"room" : {
"$elemMatch": {
"room_features" : ["Shower", "Hairdryer"]
}
},
}
Hope this help.
This is my array:
$arr = array(
0 => array(
'title' => 'test1',
'count' => 4,
'month' => 'jan-2015'
),
1 => array(
'title' => 'test2',
'count' => 10,
'month' => 'jan-2015'
),
2 => array(
'title' => 'test3',
'count' => 14,
'month' => 'jun-2015'
),
3 => array(
'title' => 'test4',
'count' => 45,
'month' => 'july-2015'
),
);
I've to convert this array into multi-dimentional array as below:
$arr = array(
'jan-2015' => array(
0 => array(
'title' => 'test1',
'count' => 4,
),
1 => array(
'title' => 'test2',
'count' => 10,
),
),
'jun-2015' => array(
0 => array(
'title' => 'test3',
'count' => 14,
),
),
'july-2015' => array(
0 => array(
'title' => 'test4',
'count' => 45,
),
),
);
I've tried to make it as expected but unfortunately i can't make this.
Is any other solutions for this?
According to your data structure :
$arr = array(
0 => array(
'title' => 'test1',
'count' => 4,
'month' => 'jan-2015'
),
1 => array(
'title' => 'test2',
'count' => 10,
'month' => 'jan-2015'
),
2 => array(
'title' => 'test3',
'count' => 14,
'month' => 'jun-2015'
),
3 => array(
'title' => 'test4',
'count' => 45,
'month' => 'july-2015'
),
);
try this:
$newArray = array();
foreach($arr as $key => $val) {
$newArray[$val['month']][] = $val;
}
echo '<pre>'.print_r($newArray,1).'</pre>';
Output:
Array
(
[jan-2015] => Array
(
[0] => Array
(
[title] => test1
[count] => 4
[month] => jan-2015
)
[1] => Array
(
[title] => test2
[count] => 10
[month] => jan-2015
)
)
[jun-2015] => Array
(
[0] => Array
(
[title] => test3
[count] => 14
[month] => jun-2015
)
)
[july-2015] => Array
(
[0] => Array
(
[title] => test4
[count] => 45
[month] => july-2015
)
)
)
You could use this function:
function transform($input) {
// Extract months, and use them as keys, with value set to empty array
// The array_fill_keys also removes duilicates
$output = array_fill_keys(array_column($input, 'month'), array());
foreach ($input as $element) {
$copy = $element;
// remove the month key
unset($copy["month"]);
// assign this to the month key in the output
$output[$element["month"]][] = $copy;
}
return $output;
}
Call it like this:
$arr = array(
0 => array(
'title' => 'test1',
'count' => 4,
'month' => 'jan-2015'
),
1 => array(
'title' => 'test2',
'count' => 10,
'month' => 'jan-2015'
),
2 => array(
'title' => 'test3',
'count' => 14,
'month' => 'jun-2015'
),
3 => array(
'title' => 'test4',
'count' => 45,
'month' => 'july-2015'
),
);
print_r (transform($arr));
Output:
Array
(
[jan-2015] => Array
(
[0] => Array
(
[title] => test1
[count] => 4
)
[1] => Array
(
[title] => test2
[count] => 10
)
)
[jun-2015] => Array
(
[0] => Array
(
[title] => test3
[count] => 14
)
)
[july-2015] => Array
(
[0] => Array
(
[title] => test4
[count] => 45
)
)
)
By using answer of #Girish Patidar, You can achieve this by:
$outputArr = array();
$to_skip = array();
foreach($arr as $row){
$to_skip = $row;
unset($to_skip['month']);
$outputArr[$row['month']][] = $to_skip;
}
echo "<pre>";
print_r($outputArr);
die;
There could many way to do this. Please try this one if it works for you
<?php
$newArr=NULL;
foreach($arr as $array)
{
$temp=NULL;
$temp['title']=$array['title'];
$temp['count']=$array['count'];
$newArr[$array['month']][]=$temp;
}
var_dump($newArr);
?>
The following question can either be solved by probably changing my use of the find method in Cake PHP OR using some PHP function. I would prefer to solve it using Cake but it doesn't matter too much. I have any array like this:
Array
(
[0] => Array
(
[Model] => Array
(
[id] => 14
[foo] => bar
)
)
[1] => Array
(
[Model] => Array
(
[id] => 15
[foo] => something
)
) .............
I just want to remove the Model index and just use the numeric one. The following function generated this array:
$arr = $this->Model->find('all', array('contain' => false ) );
I probably need to change the 'contain' part of the call. Basically, in addition to the data that appears under each Model index, I also have a second and third model and the contain = false just restricts Cake from getting data from the current model (Model).
If I understand your question correctly, I think CakePHP's Set::combine function will help http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::combine :
$result = Set::combine($your_array, '{n}.Model.id', '{n}.Model.data');
This will result in:
Array
(
[14] => Array
(
[foo] => bar
)
[15] => Array
(
[foo] => something
)
)
you have to write your own piece of code to modify your array , here is a function that will do what you want (you can improve it)
function reformArray($array,$modelName)
{
foreach($arr as $key => $value)
{
$newArr[] = $arr[$key][$modelName];
}
return $newArr;
}
you have to pass your array and the Model Name to this function and will return you the result
$a = array(
array(
'User' => array(
'id' => 2,
'group_id' => 1,
'Data' => array(
'user' => 'mariano.iglesias',
'name' => 'Mariano Iglesias'
)
)
),
array(
'User' => array(
'id' => 14,
'group_id' => 2,
'Data' => array(
'user' => 'phpnut',
'name' => 'Larry E. Masters'
)
)
),
array(
'User' => array(
'id' => 25,
'group_id' => 1,
'Data' => array(
'user' => 'gwoo',
'name' => 'The Gwoo'
)
)
)
);
RUN THIS TO REMOVE THE MODEL NAME USER
Set::extract($a, '{n}.User');
WILL RETURN THIS
$a = array(
array(
'id' => 2,
'group_id' => 1,
'Data' => array(
'user' => 'mariano.iglesias',
'name' => 'Mariano Iglesias'
)
),
array(
'id' => 14,
'group_id' => 2,
'Data' => array(
'user' => 'phpnut',
'name' => 'Larry E. Masters'
)
),
array(
'id' => 25,
'group_id' => 1,
'Data' => array(
'user' => 'gwoo',
'name' => 'The Gwoo'
)
)
);
In CakePHP 2:
$data = $this->Model->find('all');
$data = Set::extract('/Model/.', $data );
You can achieve this result by foreach also
foreach ($data as $k => &$t) {
$t = $t['Model']
}
It will be much easier with Object. Change the Array with Object.
Actually I had faced the same problem with nested array And I found the solution with Set::map($array);
If you don't want the model_name as nested array, You can prefer this solution.
$data = array(
array(
"IndexedPage" => array(
"id" => 1,
"url" => 'http://blah.com/',
'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
'get_vars' => '',
'redirect' => '',
'created' => "1195055503",
'updated' => "1195055503",
)
),
array(
"IndexedPage" => array(
"id" => 2,
"url" => 'http://blah.com/',
'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
'get_vars' => '',
'redirect' => '',
'created' => "1195055503",
'updated' => "1195055503",
),
)
);
$mapped = Set::map($data);
/* $mapped now looks like: */
Array
(
[0] => stdClass Object
(
[_name_] => IndexedPage
[id] => 1
[url] => http://blah.com/
[hash] => 68a9f053b19526d08e36c6a9ad150737933816a5
[get_vars] =>
[redirect] =>
[created] => 1195055503
[updated] => 1195055503
)
[1] => stdClass Object
(
[_name_] => IndexedPage
[id] => 2
[url] => http://blah.com/
[hash] => 68a9f053b19526d08e36c6a9ad150737933816a5
[get_vars] =>
[redirect] =>
[created] => 1195055503
[updated] => 1195055503
)
)
you may do this :
$tmp = $this->Model->find('all', array('contain' => false ) );
$arr = $tmp['ModelName'];