関数array_valuesを使用して配列を数値的にインデックス付けし、JSONにエンコードするよりも、奇妙な問題に遭遇しています。私のスクリプトがどのように動作するかを簡単に説明します。まず、クエリを介してデータベースからデータを取得し、次のように出力します。
例えば:
Array
(
[0] => Array
(
[label] => Direct
[value] => 1445
)
[1] => Array
(
[label] => Internal
[value] => 2
)
[2] => Array
(
[label] => Internal
[value] => 2
)
[3] => Array
(
[label] => Internal
[value] => 3
)
[4] => Array
(
[label] => Internal
[value] => 1
)
[5] => Array
(
[label] => Internal
[value] => 1
)
[6] => Array
(
[label] => External
[value] => 1
)
)
この関数よりも、重複するラベルを削除して値を合計します。
$sources = array();
foreach($data as $key => $values)
{
if(array_key_exists($values['label'], $sources))
{
$sources[$values['label']]['value'] += $values['value'];
$sources[$values['label']]['label'] = $values['label'];
}
else
{
$sources[$values['label']] = $values;
}
}
これを返す:
Array
(
[Direct] => Array
(
[label] => Direct
[value] => 1445
)
[Internal] => Array
(
[label] => Internal
[value] => 9
)
[External] => Array
(
[label] => External
[value] => 1
)
)
注: SQL を使用して合計値を合計することはできません。データがプルされた後にラベル direct、internal、および external が割り当てられるためです。だから提案しないでください。
それよりも、返されたフィルター処理された配列に array_values() を適用すると、次のようになります。
Array
(
[0] => Array
(
[label] => Direct
[value] => 1445
)
[1] => Array
(
[label] => Internal
[value] => 9
)
[2] => Array
(
[label] => External
[value] => 1
)
)
これまでのところ、すべてが良好です。ただし、json_encode を使用して配列を JSON に変換すると、次の文字列が返されます。
[{"label":"Direct","value":"1445"},{"label":"Internal","value":9},{"label":"External","value":"1"}]
一見、完全に問題ないように見えます。ただし、注意深く見ると、値 9 は引用符で囲まれていませんが、値 1445 と 1 は引用符で囲まれています。値 9 も引用符で囲む必要があります。
私が気付いたのは、元の配列に重複があるのはInternalだけであるため、重複を削除して値を合計する関数に問題がある可能性が高いということです。
完全なコード:
//Add up values of duplicate labels
$sources = array();
foreach($data as $key => $values)
{
if(array_key_exists($values['label'], $sources))
{
$sources[$values['label']]['value'] += $values['value'];
$sources[$values['label']]['label'] = $values['label'];
}
else
{
$sources[$values['label']] = $values;
}
}
//Assign numeric values as main key
$sources = array_values($sources);
//Print JSON
echo json_encode($sources);