Find value from multidimensional array from given two values - php

I have the following array.
Array
(
[0] => Array
(
[product] => p1
[item] => q1
[date] => d1
[status] => N
)
[1] => Array
(
[product] => p2
[item] => q2
[date] => d2
[status] => Y
)
[2] => Array
(
[product] => p1
[item] => q3
[date] => d3
[status] => N
)
)
From this array, I want date from above with the given product and value.
For Example, I have product = p2 and item = q2 as a string. Now from this array, I want a date from this array which has product = p2 and item = q2.
So I need output from the above example is: d2
I tried array_column and array_search but can't find value from product and item both.
Please help me out with this in PHP.

You can iterate over your products and check required criteria with if statement.
foreach ($products as $product) {
if ('p2' === $product['product'] && 'q2' === $product['item']) {
var_dump($product['date']);
}
}

The conditions are as a string of type
$strCond = "product = p2 and item = q2";
given?
This is converted into an array which can be processed better:
parse_str(str_replace(' and ','&',$strCond),$cond);
/*
$cond = array (
'product_' => " p2",
'item_' => " q2",
);
*/
array_filter() with a closure which cleverly uses array_intersect_assoc() delivers the result.
$result = array_filter($input,function($row) use($cond){
return array_intersect_assoc($cond, $row) === $cond;
});
Result:
array (
1 =>
array (
'product' => "p2",
'item' => "q2",
'date' => "d2",
'status' => "Y",
),
)
As a rule, with such multidimensional arrays there are always several data records in the result. You can get the date of the first record like this:
$firstDate = reset($result)['date']; //d2
Note: The algorithm was taken from PHP class tableArray.
One way of solving with this class:
$result = tableArray::create($input)
->filterEqual($cond)
->fetchRow()
;
/*
$result = array (
'product' => "p2",
'item' => "q2",
'date' => "d2",
'status' => "Y",
)
*/

Related

Sum parts of an array in php

this is quite beyond me. Appreciate some help.
I have an array in php like so:
[0] => Array
(
[cust_id] => 1006
[no_of_subs] => 2
[dlv_id] => 1000
)
[1] => Array
(
[cust_id] => 1011
[no_of_subs] => 3
[dlv_id] => 1000
)
[2] => Array
(
[cust_id] => 1012
[no_of_subs] => 5
[dlv_id] => 1001
)
[3] => Array
(
[cust_id] => 1013
[no_of_subs] => 6
[dlv_id] => 1001
)
I don't need the cust_id field. I just need to group the dlv_id and the sum of no_of_subs for each matching dlv_id. The result should look like this:
[0] => Array
(
[dlv_id] => 1000
[no_of_subs] => 5
)
[1] => Array
(
[cust_id] => 1011
[no_of_subs] => 11
)
Thank you for any help.
I don't understand the downvotes for this question. Am i doing it all wrong? Downvoting without a reason is not helping.
The simplest, most efficient way to group and sum is to perform a single loop and assign temporary associative keys.
When a row is identified as a new dlv_id row, save the two desired elements, otherwise add the no_of_subs value to the pre-existing value.
Optionally, remove the temporary keys with array_values().
Code (Demo)
$array = [
["cust_id" => 1006, "no_of_subs" => 2, "dlv_id" => 1000],
["cust_id" => 1011, "no_of_subs" => 3, "dlv_id" => 1000],
["cust_id" => 1012, "no_of_subs" => 5, "dlv_id" => 1001],
["cust_id" => 1013, "no_of_subs" => 6, "dlv_id" => 1001]
];
foreach ($array as $row) {
if (!isset($result[$row["dlv_id"]])) {
$result[$row["dlv_id"]] = ["dlv_id" => $row["dlv_id"], "no_of_subs" => $row["no_of_subs"]];
} else {
$result[$row["dlv_id"]]["no_of_subs"] += $row["no_of_subs"];
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'dlv_id' => 1000,
'no_of_subs' => 5,
),
1 =>
array (
'dlv_id' => 1001,
'no_of_subs' => 11,
),
)
Using array_column function, we can extract out dlv_id and no_of_subs separately in two different arrays, using cust_id as the key.
Now, simply loop over the array of dlv_id, and if matching key found, add the no_of_subs to it, else set the value (for the first time).
We use isset function to check if the key exists already or not.
Try the following:
// your input array is $input_array
// get all dlv_id maintaining the cust_id as index
$dlv_id = array_column($input_array, 'dlv_id', 'cust_id');
// get all no_of_subs maintaining the cust_id as index
$no_of_subs = array_column($input_array, 'no_of_subs', 'cust_id');
$output = array();
foreach ($dlv_id as $key => $value) {
if (isset($output[$value]['dlv_id'])) {
$output[$value]['dlv_id'] += $no_of_subs[$key];
} else {
$output[$value]['dlv_id'] += $no_of_subs[$key];
}
}

PHP - Array does not turn into two-dimensional array

I need to make my array better.
I am getting data from database and i have milestones and milestone_parts. i want two-dimensional array. I need data of milestones in the first dimension and milestone_parts in the second dimension.
With this code:
$query = "
SELECT
a.id AS `milestone_id`,
a.titel AS `milestone_titel`,
a.client AS `client`,
a.verkocht_id AS `milestone_verkocht_id`,
b.id AS `milestonefase_id`,
b.titel AS `milestonefase_titel`,
b.milestone_id AS `milestonefase_milestone_id`,
b.omschrijving AS `milestonefase_omschrijving`
FROM `milestones` a
INNER JOIN `milestone_parts` b ON a.id=b.milestone_id
WHERE a.verkocht_id = '99'
";
$result= $db->query($dbh, $query);
while ($row = $db->fetchassoc($result))
{
$stone = array($row['milestone_verkocht_id'], $row['milestone_id'], $row['milestone_titel'], $row['client']);
$fase = array($row['milestonefase_milestone_id'],$row['milestonefase_id'],$row['milestonefase_titel']);
$stone[] = $fase;
echo '<pre>'; print_r($stone); echo '</pre>';
}
I get this as result
Array
(
[0] => 99
[1] => 6
[2] => string
[3] => string
[4] => Array
(
[0] => 6
[1] => 10
[2] => string
)
)
Array
(
[0] => 99
[1] => 6
[2] => string
[3] => string
[4] => Array
(
[0] => 6
[1] => 11
[2] => string
)
)
but I need (with names) this:
Array
(
[milestone_verkocht_id] => 99 // This is project id
[milestone_id] => 6
[milestone_title] => string
[client] => string
[10] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 10
[milestone_title] => string
)
[11] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 11
[milestone_title] => string
)
[12] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 12
[milestone_title] => string
)
)
Can you help me or do you have a solution? Help me please!
you can cycle each field returned by the query, checking the field name and making new arrays
$stones = array();
while ($row = $db->fetchassoc($result)) {
$fase = array();
$stone = array('milestones' => array());
foreach ($row as $k => $v) {
if (strpos($k, 'milestonefase_') === 0) {
$fase[$k] = $v;
} else {
$stone[$k] = $v;
}
}
if(!isset($stones[$stone['milestone_id']])) {
$stones[$stone['milestone_id']] = $stone;
}
$stones[$stone['milestone_id']]['milestones'][$fase['milestonefase_id']] = $fase;
}
echo '<pre>'.print_r($stones, true).'</pre>';
Edit
made some changes in order to match the request. Now we use $stones to store the information we already have on a milestone, adding to it the different "$fase" returned from the query
Probably a more clean way is to retrieve all the information with two different queries one for milestones and the other for the fases
Edit2
Added a sub-array for the milestone fases

Group rows by one column and populate subarray within group with another column's value

I have an array coming from my database and simply it consists of questions and answers. I am trying to merge 2 arrays and create multidimensional array if values are more than one.
Array
(
[0] => Array
(
[question_id] => 1
[option_id] => 1
)
[1] => Array
(
[question_id] => 2
[option_id] => 3
)
[2] => Array
(
[question_id] => 3
[option_id] => 5
)
[3] => Array
(
[question_id] => 3
[option_id] => 6
)
)
I've tried to separate answers and questions to 2 different arrays but couldn't figure how to merge them again.
$user_questions = array_column($answers, 'question_id');
$user_answers = array_column($answers, 'option_id');
What I need is (question 3 has 2 answers) :
Array
(
[1] => 1
[2] => 3
[3] => Array (5, 6)
)
You can group your data like this as you fetch the results from your query instead of processing it after the fact. To get the array you have now, you're currently doing something like this:
while ($row = $stmt->someFetchMethod()) {
$result[] = $row;
}
Instead, use the question id as the key in your result array, and append the option id to an array at that key.
while ($row = $stmt->someFetchMethod()) {
$result[$row['question_id']][] = $row['option_id'];
}
Below code will create a new array by looping the existing array.
// Considering your existing array to be like this
$array = array(
'0' => array('question_id' => 1,'option_id' => 1),
'1' => array('question_id' => 2, 'option_id' => 3 ),
'2' => array('question_id' => 3,'option_id' => 5),
'3' => array('question_id' => 3,'option_id' => 6)
);
//define new array
$new_array = array();
// loop the array
foreach($array as $key=>$value){
// if the option/answer is already set to to question key
if(isset($new_array[$value['question_id']])){
// if question key is an array, push new option to that array
if(is_array($new_array[$value['question_id']])){
array_push($new_array[$value['question_id']], $value['option_id']);
}else{
// convert question key to array with the old value and new option value
$new_array[$value['question_id']] = array($new_array[$value['question_id']],$value['option_id']);
}
}
else{
// assing option as value to question key
$new_array[$value['question_id']] = $value['option_id'];
}
}
print_r($new_array);
Out put:
Array
(
[1] => 1
[2] => 3
[3] => Array
(
[0] => 5
[1] => 6
)
)

How to Remove duplicate values from Multidimentional array with single unique value in all array

I have multi-dimentional array like below,
$product = array(
"2e471a22b1b994a7cb3f3a40cee9fba2" => array (
"product" => 6004,
"unique_key" => 3a8a5cb029ee3b92cfc90de23e2329ab,
"product_id" => 51,
"line_total"=>99,
"quantity"=>1,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
),
"a7d0f813832ec8a2bf24269ff7145d0c" => array (
"product" => 6004,
"unique_key" => c30d1ca26d30aa3dc3c9aa04f0b585ce,
"product_id" => 51,
"line_total"=>99,
"quantity"=>1,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
)
);
Need to remove the duplicate values based on 'product_id' array value and increase the quantity values based on number of products.
Note: The above array have 'unique key' too so any single unique key is needed in array result.
Expected Result should be:
$resultproduct = array(
"2e471a22b1b994a7cb3f3a40cee9fba2" => array (
"product" => 6004,
"unique_key" => 3a8a5cb029ee3b92cfc90de23e2329ab,
"product_id" => 51,
"line_total"=>99,
"quantity"=>2,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
));
Working code at eval.in
I try and make the code easy to understand so more variables and lines of code than is absolutely required.
Explanation:
1) Need to use the one of original product array index as the output table key e.g. "2e471a22b1b994a7cb3f3a40cee9fba2" for product 51.
2) It needs to be fast relating input productId to the output key. So, I used a lookup table ProductIdList that matches productId to output key.
It is then a two stage lookup to find the entry in the output and add quantities to it.
The code:
// create a product_id => first key table
$productIdList = array();
// output...
$productTotal = array();
foreach ($product as $origIndex => $entry) {
$curProductId = $entry['product_id'];
// check product_id exists in the lookup...
if (isset($productIdList[$curProductId])) { // add to the total...
$productTotalIndex = $productIdList[$curProductId];
$productTotal[$productTotalIndex]['quantity'] += $entry['quantity'];
}
else { // add the entry to the output and the productIdList...
$productIdList[$curProductId] = $origIndex;
$productTotal[$origIndex] = $entry;
}
}
Output: The totals array:
Array
(
[2e471a22b1b994a7cb3f3a40cee9fba2] => Array
(
[product] => 6004
[unique_key] => 3a8a5cb029ee3b92cfc90de23e2329ab
[product_id] => 51
[line_total] => 99
[quantity] => 2
[data] => Array
(
[id] => 51
[post] => Array
(
[ID] => 51
[post_title] => Prodcut four - control
)
[price] => 99
)
)
[test02] => Array
(
[product] => 6664
[unique_key] => c30d1ca26d30aa3dc3c9aa04f0b585ce
[product_id] => 666
[line_total] => 99
[quantity] => 579
[data] => Array
(
[id] => 666
[post] => Array
(
[ID] => 666
[post_title] => Prodcut 666 - control
)
[price] => 99
)
)
)
The productId to original key list:
array (size=2)
51 => string '2e471a22b1b994a7cb3f3a40cee9fba2' (length=32)
666 => string 'test02' (length=6)
You need to loop over each product and use the product_id as the key for a new array. This adds the quantities as it goes, so should work for any quantities other than 1.
$result = [];
foreach ($product as $p)
{
if (isset($result[$p['product_id']]))
{
$result[$p['product_id']]['quantity']+= $p['quantity'];
}
else
{
$result[$p['product_id']] = $p;
}
}
print_r($result);

Pushing a sub array into the same array

I am trying to put content of one array into the same array. Here I have an array $mclass with values such as
Array
(
[0] => stdClass Object
(
[room_id] => 1,3,5
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
)
You can see I have room_id index with 1,3,5 value. Now, I want to explode the room_id and get duplicate of same array index data with change of room_id and push into the array. and finally delete the current array index such as [0]. Here I want the final result as.
Array
(
[0] => stdClass Object
(
[room_id] => 1
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
[1] => stdClass Object
(
[room_id] => 3
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
[2] => stdClass Object
(
[room_id] => 5
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
)
Here is my code for the same:
if(count($mclass)>0)
{
foreach($mclass as $mclasskey=>$mclass_row)
{
/* Room ID Calculation */
if(isset($mclass[$mclasskey]))
{
$temp_room_id = explode(',',$mclass_row->room_id);
if(count($temp_room_id)>1)
{
foreach($temp_room_id as $trkey=>$tr)
{
if(!in_array($temp_room_id[$trkey], $morning_class_semester))
{
array_push($morning_class_semester,$temp_room_id[$trkey]);
}
}
if(count($morning_class_semester)>0)
{
foreach($morning_class_semester as $mcskey=>$mcs)
{
$index_count = count($new_test);
$test[$index_count] = $mclass[$mclasskey];
$test[$index_count]->room_id = $morning_class_semester[$mcskey];
array_push($new_test,$test[$index_count]);
}
unset($mclass[$mclasskey]);
}
}
}
}
}
The code below does what you're looking for using only arrays. So you'll have to change the array access operators to -> since you're accessing an object. I'd do so, but it would break the example, so I'll leave that up to you.
Code Explained:
Loop through array selecting each subarray (object in your case), explode on the $item('room_id') ... ($item->room_id in your case) ... and create sub arrays, via loop, from that using the data from the original using each key. Remove the original item (which has the combined room_ids) and combine the placeholder and original array.
<?php
//Establish some data to work with
$array = array(
array(
"room_id" => "1,3,5",
"day" => 1,
"class_teacher" => "TEA-2014-2",
"final_exam_date" => "2015-09-21",
));
foreach ($array as $key => $item) {
$placeholder = array();
$ids = explode(',',$item['room_id']);
if (count($ids) > 1) {
foreach ($ids as $id) {
$push = array(
'room_id' => $id,
'day' => $item['day'],
'class_teacher' => $item['class_teacher'],
'final_exam_date' => $item['final_exam_date']
);
array_push($placeholder, $push);
}
$array = array_merge($array, $placeholder);
unset($array[$key]);
}
}
var_dump($array);
?>

Categories