I have this:
Array (
[0] => Array ( [f_count] => 1 [uid] => 105 )
[1] => Array ( [f_count] => 0 [uid] => 106 )
[2] => Array ( [f_count] => 2 [uid] => 107 )
[3] => Array ( [f_count] => 0 [uid] => 108 )
[4] => Array ( [f_count] => 1 [uid] => 109 )
[5] => Array ( [f_count] => 0 [uid] => 110 )
[6] => Array ( [f_count] => 3 [uid] => 111 )
)
What I need is: 7", which is the the sum of the f_count column.
I've been trying to figure this out for a couple hours. I thought array_sum() would work, but not with a multidimensional array. So, I've tried figuring out how to isolate the f_counts by unset() or splicing or anything else, but every solution seems to involve a foreach loop. I've messed with array_map, array_walk, and others to no avail. I haven't found a function that works well with multidimensional arrays.
I'm running PHP 5.4.
Can someone please show me how to sum that column without a foreach loop?
If it helps, the f_count values will never be higher than 100, and the uid values will always be greater than 100.
Alternatively, if there's a way to run my query differently such that the array is not multidimensional, that would obviously work as well.
$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array = $stmt->fetchAll();
I'm using PDO.
In php 5.5+ you can just used array_column and array_sum like so:
$value = array_sum(array_column($arr,'f_count'));
You need to couple it with array_map() to select the f_count column first:
array_sum(array_map(function($item) {
return $item['f_count'];
}, $arr));
Nowadays you can replace the inner function with array_column():
array_sum(array_column($arr, 'f_count'));
Of course, internally, this performs a double loop; it's just that you don't see it inside the code. You could use array_reduce() to get rid of one loop:
array_reduce($arr, function(&$res, $item) {
return $res + $item['f_count'];
}, 0);
However, if speed is the only interest, foreach remains the fastest:
$sum = 0;
foreach ($arr as $item) {
$sum += $item['f_count'];
}
This is thanks to the "locality" of the variables that you're using, i.e. there are no function calls used to calculate the final sum.
for these type of situation foreach loop is the best possible option but if u have to do this for multiple times on a single page then u should put foreach loop in a function so that your code remain clean
function sum_index($arr, $col_name){
$sum = 0;
foreach ($arr as $item) {
$sum += $item[$col_name];
}
return $sum;
}
Edit
After searching alot I found that array_column function exist in php 5.5 + to get all values of single column as an array.
For users having lower version You can use following function and call it with array sum if you want sum of all values as well.
//to get all values of single column from multidimensional array, this function exist in php 5.5 or greater.
if(!function_exists("array_column"))
{
function array_column($array,$column_name)
{
return array_map(function($element) use($column_name){return $element[$column_name];}, $array);
}
}
If you want to get all values of single column then call above function like this:
$newArray = array_column($array,$column_name);
If you want sum of all values of single column then use following code:
$newArraySum = array_sum(array_column($array,$column_name));
Alternatively, if there's a way to run my query differently such that
the array is not multidimensional, that would obviously work as well.
$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array = $stmt->fetchAll();
I'm using PDO.
Yes, there is another way to run your query differently. You could use the aggregate function SUM to get the sum of all the f_count directly in your query. You would combine this with $stmt->fetchColumn() to get the value of the first column (which would be the sum) of the first row (which will be the only row since we used an aggregate function).
Here is an example of how you could do this:
$query = "SELECT SUM(f_count) FROM users WHERE gid=:gid";
$stmt = $pdo->prepare($query);
$stmt->execute(array(':gid' => 'yoursearchvalue'));
$sum = $stmt->fetchColumn();
Since you are using PHP 5.4 with PDO, there could be one more way to do it (available in PHP 5.1+):
use the PDO fetchAll() function with the PDO::FETCH_COLUMN as the fetch_style, and the 0-indexed column number as the fetch_argument.
As per your example, it could be:
$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array_fcount = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
Now use the array_sum function to sum the values of the array:
$fcount_sum = array_sum($array_fcount);
You could also consult the PHP documentation at http://php.net/manual/en/pdostatement.fetchall.php
Hope this helps, and the performance could be better than looping! As already mentioned in other answers, in PHP 5.5 onwards you have the array_column() function to get $array_fcount directly from another array.
Related
I have this type of array,
Array
(
[0] => Array
(
[id] => 0
[fams] => 5
)
[1] => Array --> I want to remove this value using its index, which is "1"
(
[id] => 2
[fams] => 5
)
)
I want to remove that array [1] entirely, using its index, so the condition is - where the ID is match, for example - [id] => 2
Is that possible, to remove a particular value with that specific condition?
and without looping (or any similar method that need to loop the array)
thanks in advance!
FYI - I did try to search around, but, to be honest, I'm not sure what "keyword" do I need to use.
I did try before, but I found, array_search, array_keys - and it seems those 2 are not.
I'm okay, if we need several steps, as long as it did not use "loop" method.
---update
I forgot to mention, that I'm using old PHP 5.3.
array_filter should work fine with PHP 5.3.
The downside of this approach is that array_filter will (internally) iterate over all your array's entries, even after finding the right one (it's not a "short-circuit" approach). But at least, it's quick to write and shouldn't make much of a difference unless you're dealing with very big arrays.
Note: you should definitely upgrade your PHP version anyway!
$array = array (
0 =>
array (
'id' => 0,
'fams' => 5
),
1 =>
array (
'id' => 2,
'fams' => 5
)
);
$indexToRemove = 2;
$resultArray = array_filter($array, function ($entry) use ($indexToRemove) {
return $entry['id'] !== $indexToRemove;
});
Demo: https://3v4l.org/6DXjl
You can use array_search to find the key of a sub-array that has a matching id value (extracted using array_column), and if found, unset that element:
if (($k = array_search(2, array_column($array, 'id'))) !== false) {
unset($array[$k]);
}
print_r($array);
Output:
Array
(
[0] => Array
(
[id] => 0
[fams] => 5
)
)
Demo on 3v4l.org
It should be noted that although there is no explicit loop in this code, array_search and array_column both loop through the array internally.
You can use array_column to make id as index of the sub-array then use unset
$a = array_column($a, null, 'id');//new array id as index
$index = 2;// id to remove
if($a[$index]) unset($a[$index]);
print_r($a);
Working example :- https://3v4l.org/ofMr7
I have a multidimensional array like this:
Array (
[0] => Array
(
[time] => 1364685993
[memberid] => 131
)
[1] => Array
(
[time] => 1364685994
[memberid] => 133
)
[2] => Array
(
[time] => 1364685995
[memberid] => 141
)
)
and a single-dimensional array like this:
Array (
[0] => 131
[1] => 141
[2] => 191
[3] => 205
)
Now I want to remove all Sub-arrays from multidimensional arrays that DOES NOT contain the memberid value from normal array ?
In this case only Subaray[1] to be removed from multidimensional array as it's 'memberid' key value (133) doesn't show in normal array. Those arrays are actually pretty big, so I am not sure what would be fastest way to do it ?
$normalArray = array_flip($normalArray);
$multiDimArray = array_filter($multiDimArray, function ($elem) use ($normalArray) {
return isset($normalArray[$elem['memberid']]);
});
Requires exactly two iterations, one over each array. Key lookups using $normalArray[$elem['memberId']] are blazingly fast. May have some memory overhead due to the functional nature and copies of arrays, use a traditional loop and unset if that's an issue.
First, I would flip the $nomal array to get constant lookup time into the array, like this:
$normal = array_flip( $normal);
Then, you just have to filter the $multidimensional_array by the $normal array with a simple lookup:
$filtered = array_filter( $multidimensional_array, function( $el) use( $normal) {
return isset( $normal[ $el['member_id'] ]);
});
Don't have access to development resources at the moment to test but this should work.
foreach($members as $member => $property) {
if (!in_array($property['member_id'], $id_array)) {
unset($members[$member]);
}
}
$id_array is the 1-dimensional matrix (array) you've put in your question.
Instead of filtering the database results after the fact you may want to use the single-dimensional array in the database query itself.
We do not know what the query, you are using, looks like, but something along these lines would do it:
// The ids from the file
$use_ids = array(131, 141, 191, 205);
// Create a list for the IN clause
$ids = '(' . implode(',', $use_ids) . ')';
// Create the query
$query = <<< SQL
SELECT time, memberid
FROM some_table
WHERE ...
AND memberid IN {$ids}
ORDER BY time
SQL;
// Execute the query, etc.
It is always a good idea to let the SQL handle as much filtering of content as possible.
I have this:
Array (
[0] => Array ( [f_count] => 1 [uid] => 105 )
[1] => Array ( [f_count] => 0 [uid] => 106 )
[2] => Array ( [f_count] => 2 [uid] => 107 )
[3] => Array ( [f_count] => 0 [uid] => 108 )
[4] => Array ( [f_count] => 1 [uid] => 109 )
[5] => Array ( [f_count] => 0 [uid] => 110 )
[6] => Array ( [f_count] => 3 [uid] => 111 )
)
What I need is: 7", which is the the sum of the f_count column.
I've been trying to figure this out for a couple hours. I thought array_sum() would work, but not with a multidimensional array. So, I've tried figuring out how to isolate the f_counts by unset() or splicing or anything else, but every solution seems to involve a foreach loop. I've messed with array_map, array_walk, and others to no avail. I haven't found a function that works well with multidimensional arrays.
I'm running PHP 5.4.
Can someone please show me how to sum that column without a foreach loop?
If it helps, the f_count values will never be higher than 100, and the uid values will always be greater than 100.
Alternatively, if there's a way to run my query differently such that the array is not multidimensional, that would obviously work as well.
$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array = $stmt->fetchAll();
I'm using PDO.
In php 5.5+ you can just used array_column and array_sum like so:
$value = array_sum(array_column($arr,'f_count'));
You need to couple it with array_map() to select the f_count column first:
array_sum(array_map(function($item) {
return $item['f_count'];
}, $arr));
Nowadays you can replace the inner function with array_column():
array_sum(array_column($arr, 'f_count'));
Of course, internally, this performs a double loop; it's just that you don't see it inside the code. You could use array_reduce() to get rid of one loop:
array_reduce($arr, function(&$res, $item) {
return $res + $item['f_count'];
}, 0);
However, if speed is the only interest, foreach remains the fastest:
$sum = 0;
foreach ($arr as $item) {
$sum += $item['f_count'];
}
This is thanks to the "locality" of the variables that you're using, i.e. there are no function calls used to calculate the final sum.
for these type of situation foreach loop is the best possible option but if u have to do this for multiple times on a single page then u should put foreach loop in a function so that your code remain clean
function sum_index($arr, $col_name){
$sum = 0;
foreach ($arr as $item) {
$sum += $item[$col_name];
}
return $sum;
}
Edit
After searching alot I found that array_column function exist in php 5.5 + to get all values of single column as an array.
For users having lower version You can use following function and call it with array sum if you want sum of all values as well.
//to get all values of single column from multidimensional array, this function exist in php 5.5 or greater.
if(!function_exists("array_column"))
{
function array_column($array,$column_name)
{
return array_map(function($element) use($column_name){return $element[$column_name];}, $array);
}
}
If you want to get all values of single column then call above function like this:
$newArray = array_column($array,$column_name);
If you want sum of all values of single column then use following code:
$newArraySum = array_sum(array_column($array,$column_name));
Alternatively, if there's a way to run my query differently such that
the array is not multidimensional, that would obviously work as well.
$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array = $stmt->fetchAll();
I'm using PDO.
Yes, there is another way to run your query differently. You could use the aggregate function SUM to get the sum of all the f_count directly in your query. You would combine this with $stmt->fetchColumn() to get the value of the first column (which would be the sum) of the first row (which will be the only row since we used an aggregate function).
Here is an example of how you could do this:
$query = "SELECT SUM(f_count) FROM users WHERE gid=:gid";
$stmt = $pdo->prepare($query);
$stmt->execute(array(':gid' => 'yoursearchvalue'));
$sum = $stmt->fetchColumn();
Since you are using PHP 5.4 with PDO, there could be one more way to do it (available in PHP 5.1+):
use the PDO fetchAll() function with the PDO::FETCH_COLUMN as the fetch_style, and the 0-indexed column number as the fetch_argument.
As per your example, it could be:
$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array_fcount = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
Now use the array_sum function to sum the values of the array:
$fcount_sum = array_sum($array_fcount);
You could also consult the PHP documentation at http://php.net/manual/en/pdostatement.fetchall.php
Hope this helps, and the performance could be better than looping! As already mentioned in other answers, in PHP 5.5 onwards you have the array_column() function to get $array_fcount directly from another array.
I have an array coming from a mysql database. So it is structured this way (just the first two entry):
Array
(
[0] => Array
(
[id_cre] => CD000000001
[0] => CD000000001
[id_az] => AZ000000001
[1] => AZ000000001
)
[1] => Array
(
[id_cre] => CD000000002
[0] => CD000000002
[id_az] =>
[1] =>
)
)
I would like to count how many entries in the array have [id_az] =>''.
If I do:
count($creds)
I get 2 (the number of items in the array).
I'd prefer to reuse this array (the query runs already for another report), instead of doing a new query with the WHERE clause to subselect WHERE id_az = ''.
Any hint(s)?
This should work for you:
Just get the column id_az with array_column() and count() the array then, e.g.
echo count(array_column($creds, "id_az"));
Why not use a good old foreach loop?
$count = 0;
foreach($data as $row)
{
$count += empty($row['id_az']) ? 0 : 1;
}
or alternativly an array_map with a anonymous function
$count = 0;
array_map(function($row) use (&$count) { $count += empty($row['id_az']) ? 0 : 1; }, $data);
But this is PHP >5.3. Callbacks won't work, since you won't have access to a variable to store your count in.
This question already has answers here:
Get min and max value in PHP Array
(9 answers)
Closed 7 months ago.
I'm trying to select the maximum value for a particular key in a multidimensional array. I'm having trouble "getting to" the key in question...
So, the array (which is much more lengthy than what I'm posting here)
[0] => stdClass Object
(
[id] => 70
[cust] => 4
[dnum] => 1
[upper] => Array
(
[0] => 66
)
)
[1] => stdClass Object
(
[id] => 43
[cust] => 42
[dnum] => 2
[upper] => Array
(
[0] => 77
)
)
[2] => stdClass Object
(
[id] => 12
[cust] => 3
[dnum] => 0
[upper] => Array
(
[0] => 99
)
)
I'm trying to find the maximum "dnum" value across the entire array, so in this example, $max = 2. I know that the max function allows me to do this, but I'm not sure how to reference the dnum element without putting the whole thing in a foreach loop, and if I do that, then max wouldn't be the function to use, right?
So, I can't exactly do this:
$max = max($myarray[]->dnum);
Is there a way for me to do this without having to recreate the entire array?
In PHP 5.2 the only way to do this is to loop through the array.
$max = null;
foreach ($arr as $item) {
$max = $max === null ? $item->dnum : max($max, $item->dnum);
}
Note: I've seeded the result with 0 because if all the dnum values are negative then the now accepted solution will produce an incorrect result. You need to seed the max with something sensible.
Alternatively you could use array_reduce():
$max = array_reduce($arr, 'max_dnum', -9999999);
function max_denum($v, $w) {
return max($v, $w->dnum);
}
In PHP 5.3+ you can use an anonymous function:
$max = array_reduce($arr, function($v, $w) {
return max($v, $w->dnum);
}, -9999999);
You can use array_map() too:
function get_dnum($a) {
return $a->dnum;
}
$max = max(array_map('get_dnum', $arr));
$max = 0;
foreach($array as $obj)
{
if($obj->dnum > $max)
{
$max = $obj->dnum;
}
}
That function would work correctly if your highest number is not negative (negatives, empty arrays, and 0s will return the max as 0).
Because you are using an object, which can have custom properties/structures, I don't believe there are really any 'predefined' functions you can use to get it. Might as well just use a foreach loop.
You really can't get away from a foreach loop, as even internal functions use a foreach loop, it is just behind the scenes.
Another solution is
$numbers = array();
foreach($array as $obj)
{
$numbers[] = $obj->dnum;
}
$max = max($numbers);
The simplest way is probably your initial thought, which is to loop your array once, and pull out all the dnum keys into a separate array, then call max() on that:
$out = array();
foreach($myarray as $obj) {
$out[] = $obj->dnum;
}
echo max($out);
You could do it without creating a separate array, but you'll end up calling max() a lot more often. Performance/memory usage will be different between the two, you could always benchmark it:
$first = $myarray[0]; //assume zero start index
$max = $first->dnum;
foreach($myarray as $obj) {
$max = max($max,$obj->dnum);
}
echo $max;
The only other way you could go about it would be to sort your array using usort() and a custom sorting function based on the object dnum properties. This is probably going to be much slower than just looping your array however, so I don't think I'd recommend it unless you needed the array sorted as a side effect.
If you like oneliners
$max = max( array_map(function( $row ){ return $row->dnum; }, $myarray) );
For anyone still interested, try this...
$min = min(array_column($myarray, 'dnum'));
$max = max(array_column($myarray, 'dnum'));