Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I want to count specific strings from array values

$array = array("report=D","report=D","report=D","report=I","report=I");

I am going to count the number of D,U & I, as well as their meanings.

D = Delivered 
U = Undelivered 
I = Invalid

I am expecting an output of:

D = 3
U = 0
I = 2

First, I replace "report=" using str_replace(), then array_filter is used to count specific values.

<?php 

$array = array(
"report=D","report=D","report=D","report=I","report=I"
);

$array = str_replace("report=","",$array);

function getting_u($n) { return $n == "U"; }

function getting_d($n) { return $n == "D"; }

function getting_i($n) { return $n == "I"; }

$result_of_u = array_filter($array, "getting_u");
$result_of_d = array_filter($array, "getting_d");
$result_of_i = array_filter($array, "getting_i");

print_r($result_of_u);
print_r($result_of_d);
print_r($result_of_i);

echo "Count of U = ".count($result_of_u);
echo "\n";
echo "Count of D = ".count($result_of_d);
echo "\n";
echo "Count of I = ".count($result_of_i);
?>

See a working code here.

The code seems to work fine for me, but I'm concerned whether this is the correct/best method of procedure.

I am also unsure if my code contains any strange behaviour or present/future problems.

share|improve this question

3 Answers 3

I am not really an expert in PHP, but this can certainly be done a bit easier. First of all it seems as if you would need to iterate over the input array only once (while the ordering of the array does not matter). Hence you can use a foreach($array_to_work_on, $single_value) construct and do all the logic therein.

So the first thing to do is to split each value. You can use explode which takes as a first argument the string where the input value should be split and as a second the input itself. Since we are not interested in the first part we take only the second one (with the index 1).

Then you can make use of the "array" (or rather dictionary) data structure provided by PHP: Whenever we encounter an unseen "key" we add a new entry to the dictionary and save "1" as the number of already counted elements. In the other case (if we have already seen this key) we increment it by one.

So here is the code:

$input = array(
"report=D","report=D","report=D","report=I","report=I"
);

$stats = array();
foreach($input as $value) {
  $type = explode('=', $value)[1];
  $stats[$type] = array_key_exists($type,$stats) ? $stats[$type] + 1 : 1;
}

print_r($stats);

Note that now you also sum up also the frequency of other keys, not only "I", "O", and "U", which makes it easier to maintain or to extend.

Edit: As has been pointed out in the comments, one cannot use "function array dereferencing", i.e. $type = explode('=', $value)[1]; in older PHP versions. So the solution in this case would be to introduce a temporary variable:

$parts = explode('=', $value);
$type = $parts[1];
share|improve this answer
    
Your code has an error see here codepad.org/IKn7JzfU –  Prakash Aug 13 at 10:32
2  
The explode('=', $value)[1]; is not valid in PHP 5.3, but it's ok in PHP 5.4. php.net/manual/en/migration54.new-features.php –  arvixx Aug 13 at 10:51
    
It does work here (where I used the latest available version): sandbox.onlinephpfunctions.com/code/… –  philonous Aug 13 at 10:58
    
see my question, I want to display U = 0, How to do this ??? –  Prakash Aug 13 at 15:04
    
You can check if the key exists in the array. If it does not then you have zero elements for this key. –  philonous Aug 13 at 18:36

After calling str_replace to strip report= part you can use array_count_values function:

<?php

$array = array(
    'report=D','report=D','report=D','report=I','report=I'
);

$array = str_replace('report=', '', $array);

$defaults = array('U' => 0, 'D' => 0, 'I' => 0);
$counts = array_merge(
    $defaults,
    array_count_values($array)
);

echo 'Count of U = '.$counts['U']."\n";
echo 'Count of D = '.$counts['D']."\n";
echo 'Count of I = '.$counts['I']."\n";

Also I can't help but mention that this array('report=*',...) format seems really odd and unmaintainable.

Edit: Added array_merge to prevent 'Undefined offset' error

share|improve this answer
    
Your code has an error see here codepad.org/Ts2NZ5s9 –  Prakash Aug 14 at 5:25
    
Output shows D = 1, U = 1, I =1 But inside $array D = 3 & I = 2 –  Prakash Aug 14 at 6:01
    
Sorry for that, I updated my response with corrections –  kipelovets Sep 2 at 13:58

As I can't comment, the philonus's answer is the clearer and best for me, if you want to display zero you can do this, initializing the stats array:

$input = array(
    "report=D","report=D","report=D","report=I","report=I"
);

$stats = array(
    'U' => 0,
    'D' => 0,
    'I' => 0,
);
foreach($input as $value) {
    $types = explode('=', $value);
    $stats[$types[1]]++;
}

print_r($stats);
share|improve this answer
    
+1. (If you like my answer, you could upvote it, too ;)) –  philonous Aug 16 at 12:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.