I have a array what I'm fetching with mysql query per row, each containing the same indexes and it looks as it follows
array(
0=> array(
'order_nr'=> 123,
'order_date' => '2013-01-29 00:00:00',
'prod_name' => 'prod_1',
'prod_value' => 1200
)
1=> array(
'order_nr'=> 123,
'order_date' => '2013-01-29 00:00:00' ,
'prod_name' => 'prod_2',
'prod_value' => 2100
)
)
I would like to merge theme and make the sum of prod_value and creating a new array on prod_name and at the end I would have singe array. How would I do this in php or what would be the best workaround in this case
array(
'order_nr'=> 123,
'order_date'=>'2013-01-29 00:00:00',
'prod_name'=> array('prod_1', 'prod_2')
'prod_value' => 3300
)
If the list of products doesn't have to be an array you can use Mysql and aggregating functions. It would be something like this:
SELECT order_no, order_data, GROUP_CONCAT(prod_name SEPARATOR ',') as prod_name,
SUM(prod_value) as prod_val FROM Products WHERE ... GROUP BY order_no;
If you need the product names as arrays you can then explode the string:
explode(',', $row['prod_name']);
$aReturn = array();
foreach( $aData as $entry ) {
if( empty($aReturn[$entry['order_nr']]) ) {
$entry['prod_name'] = (array) $entry['prod_name'];
$aReturn[$entry['order_nr']] = $entry;
continue;
}
$aReturn[$entry['order_nr']]['prod_name'][] = $entry['prod_name'];
$aReturn[$entry['order_nr']]['prod_value'] += $entry['prod_value'];
}
This will group by order_nr
<?php
$arr = array(0=> array(
'order_nr'=> 123,
'order_date' => '2013-01-29 00:00:00',
'prod_name' => 'prod_1',
'prod_value' => 1200
),
1=> array(
'order_nr'=> 123,
'order_date' => '2013-01-29 00:00:00' ,
'prod_name' => 'prod_2',
'prod_value' => 2100
)
);
$sigle_arr = array();
foreach($arr as $val){
$sigle_arr[$val['order_nr']]['order_nr'] = $val['order_nr'];
$sigle_arr[$val['order_nr']]['order_date'] = $val['order_date'];
$sigle_arr[$val['order_nr']]['prod_name'][] = $val['prod_name'];
$sigle_arr[$val['order_nr']]['prod_value'] += $val['prod_value'];
}
print_r($sigle_arr);
?>
use array_merge_recursive()
that is the best option for doing it
$newarray = array();
foreach($array as $v){
if(!isset($newarray['order_nr'])){
$newarray['order_nr'] = $v['order_nr'];
}
if(!isset($newarray['order_date'])){
$newarray['order_date'] = $v['order_date'];
}
$newarray['prod_name'][] = $v['prod_name'];
$newarray['prod_value'] = $newarray['prod_value'] + $v['prod_value'];
}
$temp = Users::find('all', array('conditions' => array('status' => array('$elemMatch' => array('fields' => array('temp')));
foreach($whichs as $which)
{
foreach($which['temps'] as $temp)
{
if($temp['_id'] == $status['temp'])
{
array_push($tempsArray,$temp['status']);
}
}
}
Related
As an example I have an array like this:
$Batches = array(
$Batch_1= array(
$A_Row= array(1,1,0,0),
$B_Row = array(0,0,0,1),
$C_Row = array(0,0,0,1)),
$Batch_2= array(
$A_Row= array(1,0,0,0),
$B_Row = array(0,0,0,1),
$C_Row = array(0,0,0,1))
);
I want to sum per each $n_Row:
So I should get a result like this:
$Sum_Array = array(
$A_row=array(2,1,0,0),
$B_row= array(0,0,0,2),
$C_row = array(0,0,0,2)
);
But I'm having difficulty trying to get this result and need some tips/advice from someone else.
This is my code so far:
//count rows and columns
$count_array= count($Batches);
$count_row = count($Batches[0]);
$count_column = count($Batches[0][0]);
$Array_sum = array();
for($array=0;$array<$count_array;$array++){
for($row=0;$row<$count_row;$row++){
for($col=0;$col<$count_column;$col++){
//echo $Batches[$array][$row][$col] . "\n";
if($Batches[$array][$row][$col]==1){
$Batches[$array][$row][$col]++;
}
$Array_sum[]=$Batches[$array][$row][$col];
}
}
}
Anyone who can help me in the right direction?
Thanks in advance.
I think your "array"
$Batches = array(
$Batch_1= array(
$A_Row= array(1,1,0,0),
$B_Row = array(0,0,0,1),
$C_Row = array(0,0,0,1)),
$Batch_2= array(
$A_Row= array(1,0,0,0),
$B_Row = array(0,0,0,1),
$C_Row = array(0,0,0,1))
);
is a product of the imagination. But it is also valid PHP code. I assume you want to work with keys and the array looks like this:
$Batches = array(
'Batch_1' => array(
'A_Row' => array(1,1,0,0),
'B_Row' => array(0,0,0,1),
'C_Row' => array(0,0,0,1)),
'Batch_2' => array(
'A_Row' => array(1,0,0,0),
'B_Row' => array(0,0,0,1),
'C_Row' => array(0,0,0,1))
);
The Summation works better with foreach.
$sum_arr = [];
foreach($Batches as $ib => $batch){
foreach($batch as $ir => $row){
foreach($row as $ic => $col){
$sum_arr[$ir][$ic] ??= 0;
$sum_arr[$ir][$ic] += $col;
}
}
}
var_export($sum_arr);
The Output:
array (
'A_Row' =>
array (
0 => 2,
1 => 1,
2 => 0,
3 => 0,
),
'B_Row' =>
array (
0 => 0,
1 => 0,
2 => 0,
3 => 2,
),
'C_Row' =>
array (
0 => 0,
1 => 0,
2 => 0,
3 => 2,
),
)
The summation also works with the original array. However, this array has only numeric keys.
like the question says, I have 2 foreach cycles, 1 cycle iterates an array with 4 keys, and the other one an array with 3 keys, how to get this two arrays in only 1 ?
I have this
....
],
],
'Detalle' => array()
];
foreach ($datos["line_items"] as $line => $item) {
$tempArray = array(
'NmbItem' => $item['name'],
'QtyItem' => $item['quantity'],
'PrcItem' => $item['price'],
'IndExe' => 1
);
}
foreach($datos["fee_lines"] as $line => $fee){
$tempArray=array(
'NmbItem' => $fee['name'],
'QtyItem' => 1,
'PrcItem' => $fee['total']
);
}
$dte['Detalle'][] = $tempArray;
}
if you notice the second array cycle doesnt contain 'indexe' key, after asign this tempArray in $dte['Detalle'][] = $tempArray only works with the last cycle, or the first one if I remove the second.
the output should be something like:
temp = Array (
array[0]
'NmbItem => name',
'QtyItem'=> 10,
'PrcItem'= 1000,
'IndExe' => 1
array[1]
'NmbItem => another name',
'QtyItem'=> 5,
'PrcItem'=> 3000
)
To make it work with your code, you should also add $dte['Detalle'][] = $tempArray; after the first loop.
The issue is that you are setting the $tempArray in each foreach so you end up with only the last one when assigning it in the $dte['Detalle'].
So, something like this should work:
foreach ($datos["line_items"] as $line => $item) {
$tempArray = array(
'NmbItem' => $item['name'],
'QtyItem' => $item['quantity'],
'PrcItem' => $item['price'],
'IndExe' => 1
);
}
$dte['Detalle'][] = $tempArray;
foreach($datos["fee_lines"] as $line => $fee){
$tempArray=array(
'NmbItem' => $fee['name'],
'QtyItem' => 1,
'PrcItem' => $fee['total']
);
}
$dte['Detalle'][] = $tempArray;
However, I would do it using the array_map function.
Docs for array_map
You can have it something like this:
<?php
$data_1 = array_map(function($item){
return array(
'NmbItem' => $item['name'],
'QtyItem' => $item['quantity'],
'PrcItem' => $item['price'],
'IndExe' => 1
);
}, $datos["line_items"]);
$data_2 = array_map(function($fee){
return array(
'NmbItem' => $fee['name'],
'QtyItem' => 1,
'PrcItem' => $fee['total']
)
}, $datos["fee_lines"]);
$dte['Detalle'] = array_merge($dte['Detalle'], $data_1, $data_2);
I have an associated array,
$array2 = array(
array('customer_id' => '01', 'categories' => '',),
array('customer_id' => '02', 'categories' => '',),
array('customer_id' => '03', 'categories' => '20,26,18',),
array('customer_id' => '04', 'categories' => '45,118',),
);
I need to fetch the arrays with category value 18. I have exploded the category values and checked them in array_filter.
function testCategories($var)
{
$like = 18;
$categoryArray = array_column($var, 'categories');
foreach($categoryArray as $ca){
$caEplode = explode(',', $ca);
foreach($caEplode as $cae){
return($cae == $like);
}
}
}
print_r(array_filter($array2,"testCategories"));
But I am returning an empty string. Can any one please help me?
You don't have to use array_column() because, inside the callback of array_filter(), the categories is a key of the array in parameter. You could use in_array() with the exploded value of categories.
$array2 = array(
array('customer_id' => '01', 'categories' => '',),
array('customer_id' => '02', 'categories' => '',),
array('customer_id' => '03', 'categories' => '20,26,18',),
array('customer_id' => '04', 'categories' => '45,118',),
);
function testCategories($var)
{
$like = 18 ;
$caEplode = explode(',', $var['categories']);
return in_array($like, $caEplode) ;
}
print_r(array_filter($array2,"testCategories"));
Output:
Array
(
[2] => Array
(
[customer_id] => 03
[categories] => 20,26,18
)
)
You also could use an anonymous function and let $like outside the function:
$like = 18;
$out = array_filter($array2, function ($var) use ($like) {
$caEplode = explode(',', $var['categories']);
return in_array($like, $caEplode) ;
});
print_r($out);
I didn't use array_filter but this might be fine
<?php
$array2 = array(
array('customer_id' => '01', 'categories' => '',),
array('customer_id' => '02', 'categories' => '',),
array('customer_id' => '03', 'categories' => '20,26,18',),
array('customer_id' => '04', 'categories' => '45,118',),
);
function testCategories($var)
{
$like = 18;
foreach($var as $ca){
$caEplode = explode(',', $ca['categories']);
foreach($caEplode as $cae){
if($cae == $like)
$result[] = $ca;
}
}
return $result;
}
print_r(testCategories($array2));
?>
result
Array ( [0] => Array ( [customer_id] => 03 [categories] => 20,26,18 ) )
You can use preg_match with \b to make sure it only matches full words of "18".
$like = 18;
foreach($array2 as $val){
if(preg_match("/\b" . $like . "\b/", $val['categories'])){
$res[] = $val;
}
}
var_dump($res);
https://3v4l.org/lBKVh
Another method is to use preg_grep on the categories column and use array_intersect_key to get the matching arrays.
This means no looping is needed at all.
$like = 18;
$cat = array_column($array2, 'categories');
$match = preg_grep("/\b" . $like . "\b/", $cat);
$res = array_intersect_key($array2, $match);
var_dump($res);
https://3v4l.org/tH0n1
I don't think there will be any or much difference between this method and array_filter.
It can also be written as a one liner, harder to read but with a comment it makes a short and concise.
$res = array_intersect_key($array2, preg_grep("/\b" . $like . "\b/", array_column($array2, 'categories')));
I'm having real problems trying to figure this one out.
I have a PHP array which looks like this:
$info = array();
$info[0] = array(
'car' => 'Audi',
'previous_car' => 'BMW'
);
$info[1] = array(
'car' => 'Audi',
'previous_car' => 'Seat'
);
$info[2] = array(
'car' => 'Audi',
'previous_carg' => 'BMW'
);
$info[3] = array(
'car' => 'BMW',
'previous_car' => 'BMW'
);
$info[4] = array(
'car' => 'Ford',
'previous_car' => 'Seat'
);
I need to do some sorting on this, so the result looks like this:
Array (
car [
'Audi' => 3,
'BMW' => 1,
'Ford' => 1
],
previous_car [
'BMW' => 3,
'Seat' => 2
]
);
I need to count distinct occurrences of a value in the same key, but the search is made upon couple of arrays. I was trying to use array_value_count(), but I doesn't work well on multidimensional arrays.
I am trying to avoid the looping, since it can be overkill if the array is large.
I will be very grateful for all the help.
If you're running PHP 5.5, you can use:
$newArray = array(
'car' => array_count_values(array_column($info, 'car')),
'previous_car' => array_count_values(array_column($info, 'previous_car'))
);
var_dump($newArray);
For versions of PHP prior to 5.5
$newArray = array(
'car' => array_count_values(
array_map(
function($value) {
return $value['car'];
},
$info
)
),
'previous_car' => array_count_values(
array_map(
function($value) {
return $value['previous_car'];
},
$info
)
)
);
var_dump($newArray);
In a more object orientated way you can solve it as follows
$values = new ArrayObject();
$iterator = new RecursiveArrayIterator($info);
iterator_apply($iterator, 'countDistinct', array($iterator, $values));
function countDistinct($iterator, $values) {
while ( $iterator -> valid() ) {
if ( $iterator -> hasChildren() ) {
countDistinct($iterator -> getChildren(), $values);
} else {
if (!$values->offsetExists($iterator->key())) {
$values->offsetSet($iterator->key(), new ArrayObject());
}
if (!$values->offsetGet($iterator->key())->offsetExists($iterator->current())) {
$values->offsetGet($iterator->key())
->offsetSet($iterator->current(), 1);
} else {
$values->offsetGet($iterator->key())
->offsetSet($iterator->current(),
$values->offsetGet($iterator->key())->offsetGet($iterator->current()) + 1);
}
}
$iterator -> next();
}
}
Sure, with this example you do not avoid the loop. But with the ArrayObject and the RecursiveArrayIterator you will have some memory and performance advantages.
The result of this will exactly match your expected result, which you can easyliy iterate with the getIterator() function of the ArrayObject.
You can write a function that will sort your data but for now check this out:
http://www.php.net/manual/en/function.array-multisort.php
Here is what might help you:
$returnArray = array('car' => NULL, 'previous_car' => NULL);
foreach($info as $newInfo) {
$returnArray['car'][] = $newInfo['car'];
$returnArray['previous_car'][] = $newInfo['previous_car'];
}
$ret['car'] = array_count_values($returnArray['car']);
$ret['previous_car'] = array_count_values($returnArray['previous_car']);
var_dump($ret);
This returns:
array (size=2)
'car' =>
array (size=3)
'Audi' => int 3
'BMW' => int 1
'Ford' => int 1
'previous_car' =>
array (size=2)
'BMW' => int 3
'Seat' => int 2
I have simple array
array(
array( 'id'=>5, 'something' => 2, 'dsadsa' => 'fsfsd )
array( 'id'=>20, 'something' => 2, 'dsadsa' => 'fsfsd )
array( 'id'=>30, 'something' => 2, 'dsadsa' => 'fsfsd )
)
How to create associative array by id field (or something else) from it in the right way?
array(
'5' => array( 'something' => 2, 'dsadsa' => 'fsfsd )
'20' => array( 'something' => 2, 'dsadsa' => 'fsfsd )
'30' => array( 'something' => 2, 'dsadsa' => 'fsfsd )
)
Something along these lines.
$new_array = array();
foreach ($original_array as &$slice)
{
$id = (string) $slice['id'];
unset($slice['id']);
$new_array[$id] = $slice;
}
#NikitaKuhta, nope. There is no slice function which returns a column of values in a 2D keyed table associated with a given key or column heading. You can use some of the callback array_... functions, but you will still need to execute a custom function per element so its just not worth it. I don't like Core Xii's solution as this corrupts the original array as a side effect. I suggest that you don't use references here:
$new_array = array();
foreach ($original_array as $slice) {
$id = (string) $slice['id'];
unset($slice['id']);
$new_array[$id] = $slice;
}
# And now you don't need the missing unset( $slice)