web-dev-qa-db-ja.com

ループなしのキーによる多次元配列の合計値

私はこれを持っています:

_Array (
    [0] => Array ( [f_count] => 1 [uid] => 105 ) 
    [1] => Array ( [f_count] => 0 [uid] => 106 ) 
    [2] => Array ( [f_count] => 2 [uid] => 107 ) 
    [3] => Array ( [f_count] => 0 [uid] => 108 ) 
    [4] => Array ( [f_count] => 1 [uid] => 109 ) 
    [5] => Array ( [f_count] => 0 [uid] => 110 ) 
    [6] => Array ( [f_count] => 3 [uid] => 111 )
)
_

必要なのは_7_ "です。これは_f_count_列の合計です。

私はこれを数時間理解しようとしています。 array_sum() は機能するが、多次元配列では機能しないと思った。そこで、unset()やスプライシングなどで_f_count_ sを分離する方法を考えてみましたが、すべての解決策にはforeachループが関係しているようです。 _array_map_、_array_walk_、およびその他の機能を使用できません。多次元配列でうまく機能する関数は見つかりませんでした。

私はPHP 5.4。

誰かがforeachループなしでその列を合計する方法を教えてもらえますか?

役立つ場合は、_f_count_値が_100_より大きくなることはなく、uid値は常に_100_より大きくなります。


あるいは、配列が多次元でないようにクエリを異なる方法で実行する方法がある場合、それも明らかに機能します。

_$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array = $stmt->fetchAll();
_

PDOを使用しています。

28
David

最初に_f_count_列を選択するには、 array_map() と結合する必要があります。

_array_sum(array_map(function($item) { 
    return $item['f_count']; 
}, $arr));
_

もちろん、内部的に、これは二重ループを実行します。コード内に表示されないだけです。 array_reduce() を使用して、1つのループを取り除くことができます。

_array_reduce($arr, function(&$res, $item) {
    return $res + $item['f_count'];
}, 0);
_

ただし、速度のみが重要な場合は、foreachが最速のままです。

_$sum = 0;
foreach ($arr as $item) {
    $sum += $item['f_count'];
}
_

これは、使用している変数の「局所性」のおかげです。つまり、最終合計の計算に使用される関数呼び出しはありません。

65
Ja͢ck

PHP 5.5以降では、array_columnおよびarray_sum そのようです:

 $value = array_sum(array_column($arr,'f_count'));
72
Anthony Harley

このような状況では、foreachループが最適なオプションですが、1ページで複数回これを行う必要がある場合は、関数にforeachループを入れてコードをきれいに保つ必要があります

function sum_index($arr, $col_name){
    $sum = 0;
    foreach ($arr as $item) {
        $sum += $item[$col_name];
    }
    return $sum;
}

編集

たくさん検索した後、array_column関数はphp 5.5に存在し、単一列のすべての値を配列として取得します。

下位バージョンを使用しているユーザーの場合、次の関数を使用し、すべての値の合計も必要な場合は配列sumで呼び出すことができます。

//to get all values of single column from multidimensional array, this function exist in php 5.5 or greater.
if(!function_exists("array_column"))
{
    function array_column($array,$column_name)
    {
        return array_map(function($element) use($column_name){return $element[$column_name];}, $array);
    }
}

単一の列のすべての値を取得する場合は、上記の関数を次のように呼び出します。

$newArray = array_column($array,$column_name);

単一列のすべての値の合計が必要な場合は、次のコードを使用します。

$newArraySum = array_sum(array_column($array,$column_name));
1

あるいは、配列が多次元でないようにクエリを異なる方法で実行する方法がある場合、それも明らかに機能します。

_$query = "SELECT f_count, uid FROM users WHERE gid=:gid"; 
... 
$array = $stmt->fetchAll(); 
_

PDOを使用しています。

はい、クエリを異なる方法で実行する別の方法があります。集約関数 SUM を使用して、クエリですべての_f_count_の合計を直接取得できます。これを$stmt->fetchColumn()と組み合わせて、最初の行(集計関数を使用したので唯一の行)の最初の列(合計)の値を取得します。

これを行う方法の例を次に示します。

_$query = "SELECT SUM(f_count) FROM users WHERE gid=:gid";
$stmt = $pdo->prepare($query);
$stmt->execute(array(':gid' => 'yoursearchvalue'));
$sum = $stmt->fetchColumn();
_
1
Kodos Johnson

PDOでPHP 5.4を使用しているため、もう1つの方法があります(PHP 5.1+で利用可能):

  • _PDO::FETCH_COLUMN_を_fetch_style_として、0インデックス付きの列番号を_fetch_argument_としてPDO fetchAll()関数を使用します。

あなたの例によると、それは次のようになります:

_$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array_fcount = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
_

ここで_array_sum_関数を使用して、配列の値を合計します。

_$fcount_sum = array_sum($array_fcount);
_

PHPドキュメンテーション http://php.net/manual/en/pdostatement.fetchall.php

これが役立つことを願っています、そしてパフォーマンスはループよりも良いかもしれません!他の回答ですでに述べたように、PHP 5.5以降では、別の配列から_$array_fcount_を直接取得するarray_column()関数があります。

0
kpk