Поиск дубликатов, если найдены значения суммы

#php #php-7

#php #php-7

Вопрос:

У меня есть этот массив :

 $data = [
    0 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 14,
       'total'      => 12
    ],
    1 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 14,
       'total'      => 18
    ],
    2 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 15,
       'total'      => 10
    ]
];
  

Возврат должен быть :

 $return = [
   0 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 14,
       'total'      => 30
   ],
   1 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 15,
       'total'      => 10
   ]
];
  

Я пробовал так :

 foreach ($data as $value) {
     if(!in_array($value, $data)) {
         $result[] = $data;
     }
}
  

Идея в том, что если все поля, кроме total, являются неопределенными, то добавьте total к существующему total с теми же полями. Пожалуйста, помогите мне. Заранее спасибо и извините за мой английский

Комментарии:

1. Вам нужно будет просмотреть каждый элемент массива и сравнить дату, отдел и страну, чтобы увидеть, совпадают ли они, а затем добавить итоговые значения. Затем поместите эту информацию в новый элемент массива и удалите 2 старых. Может быть, есть более простой способ.

Ответ №1:

Вы можете сделать это, прокручивая свой массив, сравнивая все остальные значения каждого элемента ( date , department и country ) с ранее виденными значениями и суммируя итоговые значения, когда получаете совпадение. Этот код используется serialize для генерации составного ключа из других значений для сравнения:

 $output = array();
$keys = array();
foreach ($data as $value) {
    $total = $value['total'];
    unset($value['total']);
    $key = serialize($value);
    if (($k = array_search($key, $keys)) !== false) {
        $output[$k]['total']  = $total;
    }
    else {
        $keys[] = $key;
        $output[] = array_merge($value, array('total' => $total));
    }
}
print_r($output);
  

Вывод:

 Array (
    [0] => Array (
        [date] => 2018-09-12
        [department] => 12
        [country] => 14
        [total] => 30 
    )
    [1] => Array (
        [date] => 2018-09-12
        [department] => 12
        [country] => 15
        [total] => 10
     ) 
)
  

Демонстрация на 3v4l.org

Используя составной ключ в качестве индекса в $output массиве, мы можем упростить этот код, нам просто нужно использовать array_values after the loop для повторного индексирования $output массива:

 $output = array();
foreach ($data as $value) {
    $v = $value;
    unset($v['total']);
    $key = serialize($v);
    if (isset($output[$key])) {
        $output[$key]['total']  = $value['total'];
    }
    else {
        $output[$key] = $value;
    }
}
$output = array_values($output);
print_r($output);
  

Вывод такой же, как и раньше. Демонстрация на 3v4l.org

Комментарии:

1. Хороший ответ! Что делает эта строка? $output[] = array_merge($value, array('total' => $total));

2. @dmikester1 поскольку я взял total значение из $value массива, чтобы сгенерировать из него составной ключ, я должен поместить его обратно в значение, сохраняемое в $output массиве, чтобы при первом появлении составного ключа было получено итоговое значение.

3. Отмена установки и сериализация — это простой способ обеспечить уникальность в этой ситуации! Отличный ответ

Ответ №2:

Вы также можете попробовать этот метод, поскольку он не требует больших затрат памяти, таких как объединение, особенно при работе с большим объемом данных:

 $new_data=[];
foreach($data as $key=>$value){
    $i=array_search($value["date"],array_column($new_data,"date"));
    if(($i!==false)amp;amp;($new_data[$i]["department"]==$value["department"])amp;amp;($new_data[$i]["country"]==$value["country"])){
        $new_data[$i]["total"] =$value["total"];
    }
    else{
        $new_data[]=$value;
    }
}
print_r($new_data);