Asked  7 Months ago    Answers:  5   Viewed   37 times

Say I have an array like this:

$array = array('', '', 'other', '', 'other');

How can I count the number with a given value (in the example blank)?

And do it efficiently? (for about a dozen arrays with hundreds of elements each) This example times out (over 30 sec):

function without($array) {
    $counter = 0;
    for($i = 0, $e = count($array); $i < $e; $i++) {
        if(empty($array[$i])) {
            $counter += 1;
        }
    }
    return $counter;
}

In this case the number of blank elements is 3.

 Answers

58

How about using array_count _values to get an array with everything counted for you?

Wednesday, March 31, 2021
 
chugadie
answered 7 Months ago
27

If you are using PHP >= 5.5, you can use array_column(), in conjunction with array_count_values():

$colors = array_count_values(array_column($log, 0));
$materials = array_count_values(array_column($log, 1));

See demo


Or, if you're not using PHP >= 5.5, this will work in PHP 4, 5:

$colors = $materials = array();
foreach ($log as $a){
    $colors[] = $a[0];
    $materials[] = $a[1];
}

$colors = array_count_values($colors);
$materials = array_count_values($materials);

See demo 2


Click here for sample use case that will work with either method.

Wednesday, March 31, 2021
 
MKM
answered 7 Months ago
MKM
69

You can do this:

echo count($food['fruits']);
echo count($food['veggie']);

If you want a more general solution, you can use a foreach loop:

foreach ($food as $type => $list) {
    echo $type." has ".count($list). " elementsn";
}
Wednesday, March 31, 2021
 
laurent
answered 7 Months ago
61

Why don't you use DOMDocument::getElementsByTagName?

//get the number of product items
echo $doc->getElementsByTagName('productitem')->length;
 //traverse the collection of productitem
foreach($doc->getElementsByTagName('productitem') as $element){
  //$element is a DOMElement
  $nodeNames = $element->nodeName;
  $name=$element->nodeName;
  $value=$element->nodeValue;
  echo ''.$name.':'.$value.'<br>';
}

As you want to traverse your document, use XPath is just greedy. Moreover you will instantiate each node of the document even if you only want one or two.

You can use hasChildNodes methode and childNodes attribute to traverse your document

function searchInNode(DOMNode $node){

     if(isGoodNode($node)){//if your node is good according to your database
         mapTheNode($node);
     }
     if($node->hasChildNodes()){
         foreach($node->childNodes as $nodes){
             searchInNode($nodes);
         }
     }
}
searchInNode($domdocument);    
Saturday, May 29, 2021
 
PedroKTFC
answered 5 Months ago
61

I can think of a few ways:

count = numel(A( A(:)>3 & A(:)<6 ))      %# (1)

count = length(A( A(:)>3 & A(:)<6 ))     %# (2)

count = nnz( A(:)>3 & A(:)<6 )           %# (3)

count = sum( A(:)>3 & A(:)<6 )           %# (4)

Ac = A(:);
count = numel(A( Ac>3 & Ac<6 ))          %# (5,6,7,8)
%# prevents double expansion
%# similar for length(), nnz(), sum(),
%# in the same order as (1)-(4)

count = numel(A( abs(A-(6+3)/2)<3/2 ))   %# (9,10,11,12)
%# prevents double comparison and & 
%# similar for length(), nnz(), sum()
%# in the same order as (1)-(4)

So, let's test what the fastest way is. Test code:

A = randi(10, 50);
tic
for ii = 1:1e5

    %# method is inserted here

end
toc

results (best of 5 runs, all in seconds):

%# ( 1): 2.981446
%# ( 2): 3.006602
%# ( 3): 3.077083
%# ( 4): 2.619057
%# ( 5): 3.011029
%# ( 6): 2.868021
%# ( 7): 3.149641
%# ( 8): 2.457988
%# ( 9): 1.675575
%# (10): 1.675384
%# (11): 2.442607
%# (12): 1.222510

So it seems that count = sum(( abs(A(:)-(6+3)/2)<3/2 )); is the best way to go here.

On a personal note: I did not expect comparison to be slower than arithmetic in Matlab -- does anyone know an explanation for this?

Plus: why is nnz so slow compared to sum? I guess that makes sense now that I know comparison is slower than arithmetic...

Friday, July 30, 2021
 
CoderGuy123
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :