Do you know why <?= count(false) ?>
returns 1
?
Answers
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.
Assuming by 'area'
and 'source'
you mean arbitrary strings, you could nest a few loops like so:
$num_titles = 0;
foreach ($doclist as $area => $arr1) {
foreach ($arr1 as $source => $arr2) {
foreach ($arr2 as $k => $arr3) {
if (isset($arr3['title']) && strlen(trim($arr3['title'])))
$num_titles++;
}
}
}
print "Titles: {$num_titles}n";
print "Areas: " . sizeof($doclist) . "n";
Let's break down the possibilities. T::get
could return an lvalue reference (which is an lvalue expression), an rvalue reference (which is an xvalue expression), or a prvalue.
The forward
expression will convert the lvalue expression into... an lvalue expression. It will convert the xvalue into... an xvalue. And it will convert a prvalue into an xvalue.
C++'s rules about how arguments bind to parameters in overload resolution are the same for prvalue and xvalue expressions. So the last two will always call the same function.
Therefore, the outer forward
accomplishes nothing. Indeed, it is worse than doing nothing at all. Why?
Because prvalues in C++17 and above have guaranteed elision; xvalues do not. If foo
takes the parameter by value, the additional forward
will manifest an unnecessary temporary, which will then be moved into the argument. If the type is something more complex than an int
, then there's a decent chance that you're going to lose some performance.
So don't forward return values which you are going to pass directly as function arguments. If you need to store the value in an intermediary auto&&
variable, then you'll need to forward that. But if you're doing it in-situ like this, don't.
In passThroughMove(Widget&& w), w's type is already rvalue reference, std::move(w) just cast it into rvalue reference again.
So std::move(w) returns an rvalue reference, just as w itself.
No, std::move(w)
casts to rvalue, while rvalue references are lvalues.
Both functions passThroughMove
and passThrough
return by value.
They differ, however, in the way they create internally such return value.
Internally, passThroughMove
creates its return value by move. A new Widget
object (the return value) is created by moving into it, that's the effect of std::move
on the return value. passThrough
on the other hand creates its own return value by copy.
The fact that the assignment
Widget wt2 = passThrough(std::move(w2));
is done from an rvalue does not change the fact that passThrough
is forced to create its return value by copy.
In the output of the code you see the effect of the above semantics plus RVO. Without RVO both assignments should result into two additional move-constructions, which are optimized away.
It's specified behavior:
According to http://php.net/manual/en/function.count.php