Related
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).
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
have an array like this:
array (
'#attributes' =>
array (
'status' => 'ok',
),
'time_entries' =>
array (
'#attributes' =>
array (
'page' => '1',
'per_page' => '100',
'pages' => '1',
'total' => '33',
),
'time_entry' =>
array (
0 =>
array (
'time_entry_id' => '1411884',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '1.75',
'date' => '2017-02-20',
'notes' => 'What is Quadra, Events Slider, Event Page Setup',
'billed' => '0',
),
1 =>
array (
'time_entry_id' => '1411254',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '1.5',
'date' => '2017-02-17',
'notes' => 'Events Slider, Background overlay, Intro',
'billed' => '0',
),
2 =>
array (
'time_entry_id' => '1410694',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '2.75',
'date' => '2017-02-16',
'notes' => 'Background Image SVGs, Header, Footer',
'billed' => '0',
),
3 =>
array (
'time_entry_id' => '1410586',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '0.5',
'date' => '2017-02-15',
'notes' => 'Site Background
Assign Less Variables',
'billed' => '0',
),
4 =>
array (
'time_entry_id' => '1409621',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '0.25',
'date' => '2017-02-14',
'notes' => 'Theme Install',
'billed' => '0',
),
...it actually goes on further than those first 4. What I am looking to do is sort these arrays by the key ["task_id"] so that I can group those together, and then add together the ["hours"] key - so that at the end I can output the total number of hours worked on under each task_id.
I've tried a bit of 'array_merge_recursive'and similar but I'm at a loss; this is PHP a good bit above my level. Help very appreciated.
So you're probably just better off doing a group by and summation by generating a new set of data rather than trying to modify this array.
Something like this will give you what you're looking for:
$time_entries = $your_array["time_entries"]["time_entry"];
$task_hours = [];
foreach ($time_entries as $time_entry) {
if (!isset($task_hours[$time_entry["task_id"]])) {
$task_hours[$time_entry["task_id"]] = 0;
}
$task_hours[$time_entry["task_id"]] += (float) $time_entry["hours"];
}
$task_hours would give you a value like:
Array
(
[3296] => 5
[1879] => 0.25
)
Instead of sorting the array and then summing the hours why not process over the relevant part of that array and do the summation all in one go.
$tots = array();
foreach( $array['time_entry'] as $task ) {
if ( isset($tots['task_id']) ) {
$tots['task_id'] += $task['hours'];
} else {
$tots['task_id'] = $task['hours'];
}
}
You should now have an array where the key is the task_id and its value is the summation of all that keys hours.
If you want the task_id's in order then sort the $tots array before outputing any results
ksort($tots);
If you want the results in order of the number of hours
asort($tots);
I have an flat array that looks like this exemple :
array (
0 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '1',
'#NAME' => '[CDATA[nomenclature exemple]]',
'#LEVEL' => '0',
),
),
1 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '3',
'#NAME' => '[CDATA[droit]]',
'#LEVEL' => '1',
),
),
2 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '13',
'#NAME' => '[CDATA[législation]]',
'#LEVEL' => '2',
),
),
3 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '14',
'#NAME' => '[CDATA[statuts]]',
'#LEVEL' => '3',
),
),
4 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '15',
'#NAME' => '[CDATA[projets de loi]]',
'#LEVEL' => '4',
),
),
5 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '16',
'#NAME' => '[CDATA[réglementations]]',
'#LEVEL' => '2',
),
),
6 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '17',
'#NAME' => '[CDATA[instruments statutaires]]',
'#LEVEL' => '3',
),
),
7 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '2',
'#NAME' => '[CDATA[économie]]',
'#LEVEL' => '1',
),
),
8 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '8',
'#NAME' => '[CDATA[analyse cout-avantage]]',
'#LEVEL' => '2',
),
),
9 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '6',
'#NAME' => '[CDATA[analyse socio-économique]]',
'#LEVEL' => '2',
),
),
)
and I would like to have like this :
$data = array(
'[CDATA[nomenclature exemple]]' => array(
'[CDATA[droit]]' => array(
'[CDATA[législation]]' => array(
'[CDATA[statuts]]' => array(
'[CDATA[projets de loi]]'
),
),
'[CDATA[réglementations]]' => array(
'[CDATA[instruments statutaires]]'
),
),
'[CDATA[économie]]' => array(
'[CDATA[analyse cout-avantage]]',
'[CDATA[analyse socio-économique]]',
),
)
);
I can't figure out how to do it. I've found other examples here for converting flattened arrays into multidimensional ones but not where there's a custom child like this.
I should say it is a bit inconsistent to want to have the leaves in the datastructure have the [CDATA...] name as value of an indexed array, while in the rest of the tree they are keys.
So, I would suggest to make those leaves also keyed by the [CDATA...] name, but just with an empty array as value. That way the structure is consistent throughout.
For that structure you could use this function:
function buildTree($data) {
foreach($data as $i => $row) {
$arr = $row['TreePad_Fields'];
$level = $arr['#LEVEL'];
$key = $arr['#NAME'];
$levels[$level][$key] = [];
$levels[$level+1] = &$levels[$level][$key];
}
return $levels[0];
}
Call it like this:
$result = buildTree($data);
For the sample data given, the result would be:
array (
'[CDATA[nomenclature exemple]]' => array (
'[CDATA[droit]]' => array (
'[CDATA[législation]]' => array (
'[CDATA[statuts]]' => array (
'[CDATA[projets de loi]]' => array (),
),
),
'[CDATA[réglementations]]' => array (
'[CDATA[instruments statutaires]]' => array (),
),
),
'[CDATA[économie]]' => array (
'[CDATA[analyse cout-avantage]]' => array (),
'[CDATA[analyse socio-économique]]' => array (),
),
),
)
See it run on eval.in
I have an array of variable size structured like this (categories is only one of the keys inside data):
print_r($json[123]["data"]["categories"]);
array(
array(
'id' => '2',
'description' => 'Single-player'
),
array(
'id' => '1',
'description' => 'Multi-player'
),
array(
'id' => '9',
'description' => 'Co-op'
),
array(
'id' => '22',
'description' => 'Steam Achievements'
),
array(
'id' => '28',
'description' => 'Full controller support'
)
)
print_r($json[456]["data"]["categories"]);
array(
array(
'id' => '21',
'description' => 'Downloadable Content'
),
array(
'id' => '1',
'description' => 'Multi-player'
)
)
Now, I want to merge these sub-arrays (they can be in variable number) and have all keys added and replaced. I've tried array_merge but it replaces the keys without adding new ones.
In this case I need to obtain this array:
print_r($merged["data"]["categories"]);
array(
array(
'id' => '2',
'description' => 'Single-player'
),
array(
'id' => '1',
'description' => 'Multi-player'
),
array(
'id' => '9',
'description' => 'Co-op'
),
array(
'id' => '22',
'description' => 'Steam Achievements'
),
array(
'id' => '28',
'description' => 'Full controller support'
),
array(
'id' => '21',
'description' => 'Downloadable Content'
)
)
Any help?
Edit:
I think I didn't expressed myself well enough. $json[$id]["data"] has multiple keys I want to merge (categories is just an example). Also the number of $json[$id] keys is variable
Edit2:
The arrays can have duplicate values, and the depth of the keys can be variable. I need to get something like array_merge_recursive() but with same values replaced.
Edit3:
This is the current array. http://pastebin.com/7x7KaAVM I need to merge all keys that have sub-arrays
Try below code:
$json = array(
'123' => array('data' => array('categories' => array(
array(
'id' => '2',
'description' => 'Single-player'
),
array(
'id' => '1',
'description' => 'Multi-player'
),
array(
'id' => '9',
'description' => 'Co-op'
),
array(
'id' => '22',
'description' => 'Steam Achievements'
),
array(
'id' => '28',
'description' => 'Full controller support'
)
))
),
'456' => array('data' => array('categories' => array(
array(
'id' => '21',
'description' => 'Downloadable Content'
)
))
),
);
//print_r($json);
$merged = array();
foreach($json as $j1)
{
foreach($j1 as $j2)
{
foreach($j2 as $key => $j3)
{
foreach($j3 as $j4)
{
$merged[$key][] = $j4;
}
}
}
}
print_r($merged);
Result:
Array
(
[categories] => Array
(
[0] => Array
(
[id] => 2
[description] => Single-player
)
[1] => Array
(
[id] => 1
[description] => Multi-player
)
[2] => Array
(
[id] => 9
[description] => Co-op
)
[3] => Array
(
[id] => 22
[description] => Steam Achievements
)
[4] => Array
(
[id] => 28
[description] => Full controller support
)
[5] => Array
(
[id] => 21
[description] => Downloadable Content
)
)
)
Demo:
http://3v4l.org/X61bE#v430
Try this . To generalize I have added some more arrays.
<?php
$merged_array = array();
$final_array = array();
$json[123]["data"]["categories"] = array(
array(
'id' => '2',
'description' => 'Single-player'
),
array(
'id' => '1',
'description' => 'Multi-player'
),
array(
'id' => '9',
'description' => 'Co-op'
),
array(
'id' => '22',
'description' => 'Steam Achievements'
),
array(
'id' => '28',
'description' => 'Full controller support'
)
);
$json[456]["data"]["categories"] = array(
array(
'id' => '21',
'description' => 'Downloadable Content'
)
);
$json[786]["data"]["categories"] = array(
array(
'id' => '31',
'description' => 'Downloadable Content'
)
);
$json[058]["data"]["categories"] = array(
array(
'id' => '41',
'description' => 'Downloadable Content'
)
);
foreach($json as $key=>$value){
array_push($merged_array,$json[$key]["data"]["categories"]);
}
foreach($merged_array as $value){
foreach($value as $val){
array_push($final_array,$val);
}
}
print_r($final_array);
?>
RESULT
Array
(
[0] => Array
(
[id] => 2
[description] => Single-player
)
[1] => Array
(
[id] => 1
[description] => Multi-player
)
[2] => Array
(
[id] => 9
[description] => Co-op
)
[3] => Array
(
[id] => 22
[description] => Steam Achievements
)
[4] => Array
(
[id] => 28
[description] => Full controller support
)
[5] => Array
(
[id] => 21
[description] => Downloadable Content
)
[6] => Array
(
[id] => 31
[description] => Downloadable Content
)
[7] => Array
(
[id] => 41
[description] => Downloadable Content
)
)