4

多次元配列の特定の値の日付が類似している場合、その値を合計する方法を見つけようとしています。

これが私の配列です:

<?$myArray=array(

array(
        'year' => 2011,
        'month ' => 5,
        'day' => 13,
        'value' => 2
    ),
array(
        'year' => 2011,
        'month '=> 5,
        'day' => 14,
        'value' => 5
    ),
array(
        'year' => 2011,
        'month ' => 5,
        'day' => 13,
        'value' => 1
    ),
array(
        'year' => 2011,
        'month ' => 5,
        'day' => 14,
        'value' => 9
    )
);?>

出力を次のように表示します。

<?$output=array(

array(
        'year' => 2011,
        'month ' => 5,
        'day' => 13,
        'value' => 3 //the sum of 1+2
    ),
array(
        'year' => 2011,
        'month '=> 5,
        'day' => 14,
        'value' => 14 //the sum of 5+9
    )
);?>

4 つのサブ配列がどのように一致しyear/month/day、次に のみvalueが合計されたかに注意してください。このトピックに関する他のSOスレッドを見てきましたvalueが、値だけではなく合計されているものを見つけることができませんyear/month/day

考え?

4

2 に答える 2

4

最初に年/月/日の組み合わせで出力配列にインデックスを付けるのが最も簡単な場合があります。

:上記の例の配列にはmonth、末尾にスペースがあるすべてのキーがあります。monthここでは、末尾のスペースなしで使用しています。

// Initialize output array...
$out = array();

// Looping over each input array item
foreach ($myArray as $elem) {
  // Initialize a new element in the output keyed as yyyy-mm-dd if it doesn't already exist
  if (!isset($out[$elem['year'] . "-" . $elem['month '] . "-" . $elem['day']])) {
    $out[$elem['year'] . "-" . $elem['month '] . "-" . $elem['day']] = array(
      // Set the date keys...
      'year' => $elem['year'],
      'month' => $elem['month '],
      'day' => $elem['day'],
      // With the current value...
      'value' => $elem['value']
    );
  }
  // If it already exists, just add the current value onto it...
  else {
     $out[$elem['year'] . "-" . $elem['month '] . "-" . $elem['day']]['value'] += $elem['value'];
  }
}

// Now your output array is keyed by date.  Use array_values() to strip off those keys if it matters:
$out = array_values($out);

出力 ( を呼び出す前array_values()):

array(2) {
  '2011-5-13' =>
  array(4) {
    'year' =>
    int(2011)
    'month' =>
    int(5)
    'day' =>
    int(13)
    'value' =>
    int(3)
  }
  '2011-5-14' =>
  array(4) {
    'year' =>
    int(2011)
    'month' =>
    int(5)
    'day' =>
    int(14)
    'value' =>
    int(14)
  }
}

アップデート:

単一のキー日付 (3 つの部分ではなく) で同じことを行うには、連結を使用しないほうが簡単です。

$myArray=array(
      array(
            'date' => '2011-05-13',
            'value' => 2
        ),
    array(
            'date' => '2011-05-14',
            'value' => 5
        ),
        array(
            'date' => '2011-05-13',
            'value' => 7
        ),
    array(
            'date' => '2011-05-14',
            'value' => 3
        ),

);

   foreach ($myArray as $elem) {
      // Initialize a new element in the output if it doesn't already exist
      if (!isset($out[$elem['date']])) {
        $out[$elem['date'] = array(
          // Set the date keys...
          'date' => $elem['date'],
          // With the current value...
          'value' => $elem['value']
        );
      }
      else {
        $out[$elem['date']]['value'] += $elem['value'];
      }
    }
于 2012-08-27T12:43:15.430 に答える
2

これが私がそれをする方法です。結果は$newArray、日時オブジェクトをキーとして使用されます。インデックス付き配列として使用するだけの場合は、非常に簡単です。

// Example array
$myArray = array(
    array(
    'date' => new DateTime('1993-08-11'),
    'value' => 3
    ),

    array(
    'date' => new DateTime('1993-08-11'),
    'value' => 5
    )
);

$newArray = array();

foreach($myArray as $element)
{
    $iterationValue = $element['value'];
    $iterationDate = $element['date'];
    $dateKey = $iterationDate->format('Y-m-d');

    if(array_key_exists($dateKey, $newArray))
    {
        // If we've already added this date to the new array, add the value
        $newArray[$dateKey]['value'] += $iterationValue;
    }
    else
    {
        // Otherwise create a new element with datetimeobject as key
        $newArray[$dateKey]['date'] = $iterationDate;
        $newArray[$dateKey]['value'] = $iterationValue;
    }
}

nl2br(print_r($newArray));

実際には、@MichaelBerkowskiソリューションとほぼ同じことを行うことになりました。それでも、アプリケーションの後半で日付を処理したくない場合は、DateTimeオブジェクトを使用する方が常に柔軟性があります。

編集:テストし、エラーを修正しました

于 2012-08-27T13:05:59.490 に答える