在数组中添加值

时间:2015-06-28 05:46:21

标签: php arrays

我正在尝试计算由一个或多个零(0)分隔的数组中的元素。

示例:

  

[1,2,4,0,9,8,4,0,0,7,1,2,6]

     

1 + 2 + 4,9 + 8 + 4,7 + 1 + 1 + 2 + 6

     

输出:[7,21,16]

我写了以下函数:

function countElementsInArray(){
    $array = [1,2,4,0,9,8,4,0,7,1,2,6];

    $countArr = [];
    $count = 0;
    $test = 0;

    for($i = 0; $i < count($array); $i++){
        if( $array[$i] != 0 ) {
           $count += $array[$i];
        } 
        //else if($array[$i] == 0 || $array[$i - 1] == 0){
        else{
            $count = 0;
            $test += 1;
        }
        $countArr[$test] = $count;
    }
    return $countArr;
}

如果数组中只有一个“0”,这样可以正常工作。如果我有两个零,我无法弄清楚如何将值相加。知道如何解决这个问题吗?

修改: 问题是我有这样的数组:[1,2,4,0,9,8,4,0,0,7,1,2,6]彼此相邻的两个“0”:print_r(countElementsInArray ())

Array ( [0] => 7 [1] => 21 [2] => 0 [3] => 16 )

我想要达到的目的是:

Array ( [0] => 7 [1] => 21 [2] => 16 )

5 个答案:

答案 0 :(得分:3)

为了解决您的问题&#34;不止一个&#39; 0&#39;在阵列&#34;当您达到sum值时,您需要重置0变量并增加key,以便开始计算新的值子集的总和。

编辑:如果另一个旁边有多个零,则代码将取消设置该总和,然后使用相同的$i(密钥)重新开始。

编辑2:关于@Stuart Wagner的评论,为了确保代码没有设置合法的总和(例如:[-2,1,1]),我添加了一个包含的新变量最后value$previousVal)。如果该值不是0sum0,那么它是一个合法的零和,否则 - 不是。

编辑3:由于评论中提及@ Rizier123,因为第一个循环$previousVal上的内容未设置,主要条件将返回false。解决方案是在循环之前设置变量。

编辑4:如果尾随零,只需将其从数组中删除,因为它没有影响(不要在子集之间分开)。

function countElementsInArray($array){

   $sumArr = array();
   $i = 0;
   $sumArr[$i] = 0;
   $previousVal = 0;

   if(last($array) == 0)
     array_pop($array);

   foreach($array as $val){
     if($val == 0){
        if($sumArr[$i] == 0 && isset($previousVal) && $previousVal == 0){
          unset($sumArr[$i]);
        } else {
          $i++;
        }
        $sumArr[$i] = 0;
     }
     $sumArr[$i] += $val;
     $previousVal = $val;
   }
   return $sumArr;
}

$array = [1,2,4,0,9,8,4,0,7,1,2,6];
print_r(countElementsInArray($array));


$array = [3,2,1,0,5,4,0,0,8,4];
print_r(countElementsInArray($array));

$array = [-2,1,1,0,5,4,0,0,8,4];
print_r(countElementsInArray($array));

$array = [0,0,0,-2, 1, 1, 0, 5, 4, 0,0,0, 0, 8, 4,0,-3,2,1];
print_r(countElementsInArray($array)); 

输出:

Array
(
    [0] => 7
    [1] => 21
    [2] => 16
)
Array
(
  [0] => 6
  [1] => 9
  [2] => 12 
)
Array
(
  [0] => 0
  [1] => 9
  [2] => 12
)
Array
(
  [0] => 0
  [1] => 9
  [2] => 12
  [3] => 0
)

Demo

答案 1 :(得分:1)

这已经很晚了,但为了完整起见,这是另一种解决方案,它利用了其他答案的一些最佳部分,并解释了前导零,尾随零和零和等事项。我相信它也是最简单的。

function countSeparatedElements($array, $seperator = 0)
{
    $array[] = $seperator;
    $result = [];
    $i = 0;

    foreach ($array as $val) {
        if ($val == $seperator) {
            if (! empty($result[$i])) {
                $result[$i] = array_sum($result[$i]);
                $i++;
            }
            continue;
        }
        $result[$i][] = $val;
    }

    return ! empty($result) ? $result : false;
}

$array = [0, 1, 2, 4, 0, 9, 8, 4, 0, 0, -2, 1, 1, 0, 0, 7, 1, 2, 6, 0];
$output = countSeparatedElements($array);
print_r($output);

输出:

Array
(
    [0] => 7
    [1] => 21
    [2] => 0
    [3] => 16
)

答案 2 :(得分:0)

这应该适合你:

在这里,我只需浏览每个元素并将其添加到$countArr。如果我们检查0,我检查,如果计数数组只包含0。如果是,我重置计数数组并continue;其他我array_sum()这些值并重置数组。

最后我只检查我们是否没有空数组,如果不是,我将最后一笔加到$result数组中。

<?php

    function countSeparatedElements(array $array) {
        $countArr = [];

        foreach($array as $v) {
            $countArr[] = $v;
            if($v == 0) {
                if(count(array_unique($countArr)) === 1 && end($countArr) === 0) {
                    $countArr = [];
                    continue;
                } else {
                    $result[] = array_sum($countArr);
                    $countArr = [];
                }
            }

        }

        if(!empty($countArr))
            $result[] = array_sum($countArr);
        return $result; 

    }

    $array = [3, 2, 1, 0, 5, 4, 0, 0, 8, 4];
    $counts = countSeparatedElements($array);
    print_r($counts);

?>

输出:

Array
(
    [0] => 6
    [1] => 9
    [2] => 12
)

修改

另一个解决方案就是用引号逗弄你的字符串,然后将其爆炸。在此之后,您可以选择array_sum()

<?php

    $array = [0, 1, 2, 4, 0, 9, 8, 4, 0, 0, -2, 1, 1, 0, 0, 7, 1, 2, 6, 0];
    $str = array_reduce($array, function($keep, $v){
        return $keep .= "," . $v;
    }, "");

    $arr = preg_split("/,0/", $str, -1, PREG_SPLIT_NO_EMPTY);
    $counts = array_map(function($v){
        return array_sum(explode(",", $v));
    }, $arr);

    print_r($counts);


?>

输出:

Array
(
    [0] => 7
    [1] => 21
    [2] => 0
    [3] => 16
)

答案 3 :(得分:0)

我不喜欢所有这些循环变量的东西,所以我要做一些正则表达式魔术:

    $array = [1,2,4,0,9,8,4,0,0,7,1,2,6,0,0,0,10,20,30,0,0,0,1,2,3,6,0,0,0,4];


function custom_count($a){

    $str = implode('|',$a); // array to string
    $str = preg_replace('/(\|0)+/','|0',$str); // repllce multiple 0's, Regey magic
    $new = explode('|',$str);

    $res = [0];
    $key = 0;
    foreach($new as $num){
        if($num == 0) {
            $key++;
            $res[$key] = 0;
        }
        else
            $res[$key] += $num;
    }
    return $res;
}

var_dump(custom_count($array));

/*
 * [0]=>
  int(7)
  [1]=>
  int(21)
  [2]=>
  int(16)
  [3]=>
  int(60)
  [4]=>
  int(12)
  [5]=>
  int(4)
}
 */

答案 4 :(得分:0)

$res = Array_reduce($array, 
             function($c, $v) {
                if($v) { 
                   if (!$c[1]) $c[0][] = $v;
                   else $c[0][count($c[0])-1] += $v;
                   $c[1]++; }
                else $c[1] = 0;
                return $c;
             }, [[],0])[0];

使用前导和尾随零和空数组

$array = [0,1,2,3,0,0,-1,1,0];  // $res = array(6, 0);
$array = [];  // $res = array();