У меня есть массивы $vd_arr
array (size=3) 0 => array (size=3) 'delivnote_id' => string '1' (length=1) 'qty' => string '76' (length=2) 'id' => int 17 1 => array (size=3) 'delivnote_id' => string '1' (length=1) 'qty' => string '87' (length=2) 'id' => int 16 2 => array (size=3) 'delivnote_id' => string '1' (length=1) 'qty' => string '889' (length=3) 'id' => int 17
Мне нужно объединить по id и сумму значения qty, поэтому результат будет:
array (size=2) 0 => array (size=3) 'id' => int 17 'qty' => int 965 'delivnote_id' => string '1' (length=1) 1 => array (size=3) 'id' => int 16 'qty' => int 87 'delivnote_id' => string '1' (length=1)
этот скрипт выполняет эту работу, но php замечает меня undefined index: qty
$vendel = array(); $indexArray = array(); foreach ($vd_arr as $miniarray) { $vendel[$miniarray['id']]['id'] = $miniarray['id']; $vendel[$miniarray['id']]['qty'] += $miniarray['qty']; $vendel[$miniarray['id']]['delivnote_id'] = $miniarray['delivnote_id']; } foreach($vendel as $value) { $indexArray[] = $value; } return $indexArray;
как избежать undefined index
из сценария выше? Благодарю.
Попробуй это
$vendel = array(); $indexArray = array(); foreach ($vd_arr as $miniarray) { $vendel[$miniarray['id']]['id'] = $miniarray['id']; if(isset($vendel[$miniarray['id']]['qty'])) { $vendel[$miniarray['id']]['qty'] += $miniarray['qty']; } else { $vendel[$miniarray['id']]['qty'] = $miniarray['qty']; } $vendel[$miniarray['id']]['delivnote_id'] = $miniarray['delivnote_id']; } foreach($vendel as $value) { $indexArray[] = $value; } return $indexArray;
-$vendel = array(); $indexArray = array(); foreach ($vd_arr as $miniarray) { $vendel[$miniarray['id']]['id'] = $miniarray['id']; if(isset($vendel[$miniarray['id']]['qty'])) { $vendel[$miniarray['id']]['qty'] += $miniarray['qty']; } else { $vendel[$miniarray['id']]['qty'] = $miniarray['qty']; } $vendel[$miniarray['id']]['delivnote_id'] = $miniarray['delivnote_id']; } foreach($vendel as $value) { $indexArray[] = $value; } return $indexArray;
Адаптированный код для включения проверки свойств массива существует до их доступа:
$vendel = array(); $indexArray = array(); foreach ($vd_arr as $miniarray) { // Skips adding this mini array if an ID is note present if(($id = isset($miniarray['id']) ? $miniarray['id'] : null) === null) { continue; } // The default values at the end of these lines can be swapped out for more suitable defaults $qty = isset($miniarray['qty']) ? $miniarray['qty'] : 0; $delivnote_id = isset($miniarray['delivnote_id']) ? $miniarray['delivnote_id'] : null; $vendel[$id]['id'] = $id; $vendel[$id]['qty'] += $qty; $vendel[$id]['delivnote_id'] = $delivnote_id; } foreach($vendel as $value) { $indexArray[] = $value; } return $indexArray;
Это также пропускает добавление элемента $ miniarray, у которого нет «id».
Как уже упоминалось, просто проверьте, есть ли qty isset перед добавлением к нему:
$vendel = array(); $indexArray = array(); foreach ($vd_arr as $miniarray) { $vendel[$miniarray['id']]['id'] = $miniarray['id']; $vendel[$miniarray['id']]['delivnote_id'] = $miniarray['delivnote_id']; // the magic is in the next line if(!isset($vendel[$miniarray['id']]['qty'])) $vendel[$miniarray['id']]['qty'] = 0; $vendel[$miniarray['id']]['qty'] += $miniarray['qty']; } foreach($vendel as $value) { $indexArray[] = $value; } return $indexArray;
-$vendel = array(); $indexArray = array(); foreach ($vd_arr as $miniarray) { $vendel[$miniarray['id']]['id'] = $miniarray['id']; $vendel[$miniarray['id']]['delivnote_id'] = $miniarray['delivnote_id']; // the magic is in the next line if(!isset($vendel[$miniarray['id']]['qty'])) $vendel[$miniarray['id']]['qty'] = 0; $vendel[$miniarray['id']]['qty'] += $miniarray['qty']; } foreach($vendel as $value) { $indexArray[] = $value; } return $indexArray;
с некоторым рефакторингом мы могли бы избавиться от второго цикла цикла, если мы используем 'id' как ключ от $ indexArray
$vendel = array(); $indexArray = array(); foreach ($vd_arr as $miniarray) { if(!isset($indexArray[$miniarray['id']])) { $indexArray[$miniarray['id']] = array( 'delivnote_id' => $miniarray['delivnote_id'] ,'qty' => 0 ); } $indexArray[$miniarray['id']]['qty'] += $miniarray['qty']; } return $indexArray;
Или, если вам нужно, чтобы эти индексы были численными
$vendel = array(); $indexArray = array(); foreach ($vd_arr as $miniarray) { if(!isset($indexArray[$miniarray['id']])) { $indexArray[$miniarray['id']] = array( 'id' => $miniarray['id'] ,'delivnote_id' => $miniarray['delivnote_id'] ,'qty' => 0 ); } $indexArray[$miniarray['id']]['qty'] += $miniarray['qty']; } return array_values($indexArray);
этот другой подход с использованием функционального программирования
<?php $data = json_decode('[ { "id": 1, "value1": 5, "value2": 10 }, { "id": 2, "value1": 50, "value2": 100 }, { "id": 1, "value1": 1, "value2": 2 }, { "id": 2, "value1": 15, "value2": 20 }, { "id": 3, "value1": 15, "value2": 20 } ]'); //print_r(array_group_by($data,'id')); print_r(array_sum_by($data,'id',['value1','value2'])); //print_r(array_sum(array_column($data,'value1'))); function array_sum_by($array,$group,$keys) { $groupeddata = array_group_by($array,$group); return array_map(function($items) use($group,$keys) { foreach($keys as $key) { $values[$key] = array_sum(array_column($items,$key)); } $first = array_shift($items); if(is_object( $first ) && isset( $first->{ $group } )){ $values = array_merge([ $group => $first->{ $group } ], $values); }elseif(isset($first[$group])){ $values = array_merge([ $group => $first[$group] ], $values); } return $values; },$groupeddata); } function array_group_by( array $array, $key ) { if ( ! is_string( $key ) && ! is_int( $key ) && ! is_float( $key ) && ! is_callable( $key ) ) { trigger_error( 'array_group_by(): The key should be a string, an integer, or a callback', E_USER_ERROR ); return null; } $func = ( is_callable( $key ) ? $key : null ); $_key = $key; // Load the new array, splitting by the target key $grouped = []; foreach ( $array as $value ) { if ( is_callable( $func ) ) { $key = call_user_func( $func, $value ); } elseif ( is_object( $value ) && isset( $value->{ $_key } ) ) { $key = $value->{ $_key }; } elseif ( isset( $value[ $_key ] ) ) { $key = $value[ $_key ]; } else { continue; } $grouped[ $key ][] = $value; } // Recursively build a nested grouping if more parameters are supplied // Each grouped array value is grouped according to the next sequential key if ( func_num_args() > 2 ) { $args = func_get_args(); foreach ( $grouped as $key => $value ) { $params = array_merge( [ $value ], array_slice( $args, 2, func_num_args() ) ); $grouped[ $key ] = call_user_func_array( 'array_group_by', $params ); } } return $grouped; }