给出一个数字,foreach第三位做某事

Lets say i have a number like below:

$number = "20160513123"

So what i want to do is, Starting from 2, for each third digit i want to multiply and find the sum. So basically i want to get the number 2,6,1,2 from the string and multiply each number by 3 and then calculate the sum of all the multiplication. Like so:

2 * 3, 
6 * 3,
1 * 3,
2 * 3,

Then i want to get the sum of all of the above. How is that possible using PHP?

You could use the range function to step through your characters:

$number = "20160513123";

$sum = 0;
foreach (range(0, strlen($number), 3) as $i) {
    $sum += 3*$number[$i];
}

echo $sum;

Output:

33

If you like functional programming, then this may be according to your liking:

$sum = 3 * array_sum(array_map(
           function($i) use ($number) { return $number[$i]; },
           range(0, strlen($number), 3)
       ));

Or, with the use of str_split, you can get chunks of 3 characters:

$sum = array_sum(array_map(
           function($s) { return 3*$s[0]; },
           str_split($number, 3)
       ));

NB: Note that you can either multiply each number with 3 separately, or just the sum.

Compact solution

One final alternative. It uses array_chunk and array_column to filter out the desired digits (it seems PHP has functions for most anything):

$sum = 3 * array_sum(array_column(array_chunk(str_split($number), 3), 0));

Take your pick ;-)

CasimiretHippolyte's tiny, tiny one-liner

(you're not going to find a smaller one-liner for this question):

echo array_sum(preg_split('/.\K..?/',$number))*3;

This explodes $number after this first character by every 2 (or 1) character to follow, adds up the remaining numbers and multiplies them. Just clever awesome!


CasimiretHippolyte's previous solution:

if(preg_match_all('/..\K./',"00$number",$matches)){
    echo array_sum($matches[0])*3;
}

Though it required left-padding the string, this method used shorter/simpler regex and produced a leaner $matches array, compared to my solution below:


mickmackusa's solution:

if(preg_match_all("/(\d)(?:\d\d|\d$|$)/",$number,$matches)){
    echo array_sum($matches[1])*3;
}

My regex matches all single digits that are followed by either: 2 digits, 1 digit & end of line, or end of line. This method steps past the non-capture group digits when it can, so only 1st, 4th, 7th, etc. are captured.

All codes above output:

33

The solution using str_split function(to get an array of digits):

$number = "20160513123";
$total_sum = 0;
foreach (str_split($number) as $k => $n) {
    if ($k % 3 == 0) $total_sum += $n * 3;  // considering each third digit
}

print_r($total_sum);   // 33