迭代数组中的前30个键

迭代数组中的前30个键

问题描述:

I have an array stored into a variable called $data

["data"]=>
  array(413) {
    [0]=>
    object(stdClass)#254 (7) {
      ["Energy"]=>
      string(7) "44555"
      ["Closing"]=>
      string(10) "102"
    }
    [1]=>
    object(stdClass)#260 (7) {
      ["Energy"]=>
      string(7) "2522"
      ["Closing"]=>
      string(10) "854"
    }

And I obtain an arithmetic mean for all the Closing values like this:

// initialize sum and total
$sum = 0;
$total = 0;

foreach ($data->data as $obj) {
    if (isset($obj->Closing)) {   // verify that the current object has a Closing
        $sum += $obj->Closing;    // add it to the sum
        $total++;                  // increment the count
    }
}
echo $sum / $total;                // display the average

The problem is that now I will only need the first 30 key from the array, but I don't know how to do that, can anyone help me please? I have tried with a for loop but it doesn't do the trick. Any ideas? Thank you all in advance for your time and help.

我有一个存储在名为 $ data code> p> 的变量中的数组

  [“data”] => 
 array(413){
 [0] => 
 object(stdClass)#254(7){
 [“Energy”]  => 
 string(7)“44555”
 [“Closing”] => 
 string(10)“102”
} 
 [1] => 
 object(stdClass)#260  (7){
 [“Energy”] => 
 string(7)“2522”
 [“Closing”] => 
 string(10)“854”
} 
  code  >  pre> 
 
 

我得到所有Closing值的算术平均值,如下所示: p>

  //初始化sum和total 
 $ sum  = 0; 
 $ total = 0; 
 
foreach($ data-> data as $ obj){
 if(isset($ obj-> Closing)){//验证当前对象是否有 结束
 $ sum + = $ obj->结束;  //将它添加到总和
 $ total ++;  //递增计数
} 
} 
echo $ sum / $ total;  //显示平均值
  code>  pre> 
 
 

问题是现在我只需要数组中的前30个键,但我不知道怎么做, 有人可以帮我吗? 我尝试过for循环,但它没有做到这一点。 有任何想法吗? 提前感谢大家的时间和帮助。 p> div>

Using your second piece of code :

$sum = 0;
$total = 0;

foreach ($data->data as $obj) {
    if (isset($obj->Closing) && $total < 30) {   // Closing? + numOfValues < 30 ?
        $sum += $obj->Closing;
        $total++;
    }
}

// Display the average
echo $sum / $total;

Adding && $total < 30 should do the trick since you count how many items you add.


You can break out of the for if you don't want to do extra loops with a single extra condition :
(thanks Adam for pointing this out)
foreach ($data->data as $obj) {
    if (isset($obj->Closing) && $total < 30) {
        // ...
    }
    else if ($total >= 30) break;
}

To get first N elements of an array, use array_slice() function.

$output = array_slice($input, 0, 30);

The problem with the current answer is that it won't actually break out of the loop when it reaches 30. Surely, it's just a case of breaking out when $total=30?

// initialize sum and total
$sum = 0;
$total = 0;
$max = 30;

foreach ($data->data as $obj) {
    if (isset($obj->Closing)) { 
        $sum += $obj->Closing;
        $total++;
        if($total==$max){
            break;
        }  
    }
}

In case you love iterators. You can do it combining CallbackFilterIterator and LimitIterator

$iterator = new ArrayIterator($data->data);
$filtered = new CallbackFilterIterator($iterator, function ($current, $key, $iterator) {
    return isset($current->Closing);
});
//now $filtered have only objects with Closing property
$limited = new LimitIterator($filtered, 0, 30);
$sum = 0;
foreach ($limited as $obj) {
    $sum += $obj->Closing;
}
echo $sum/iterator_count($limited);

So there is this old school way of doing things called a for loop.

$dataArray = $data->data;

for($i = 0; $i <= 30; $i++){
    $obj = $dataArray[$i]; //Just like the object you have.
    //Do your thing with $obj.
    //Loop will only run 30 times
}

I was not sure the structure of your array but $data->data seems to be an array.