php записать повторяющееся значение и добавить в новый массив (многомерный массив)

#php #arrays

#php #массивы

Вопрос:

У меня есть массив данных, подобный этому

 Array
(
    [0] => Array
        (
            [MACHINE] => A1
            [LOT] => B1077
            [slot] => 1
        )
    [1] => Array
        (
            [MACHINE] => A2
            [LOT] => B0229           
            [slot] => 2
        )
    [2] => Array
        (
            [MACHINE] => A2
            [LOT] => B0132
            [slot] => 2
        )
    [3] => Array
        (
            [MACHINE] => A2
            [LOT] => B3967
            [slot] => 2
        )               
    [4] => Array
        (
            [MACHINE] => A3
            [LOT] => B2644
            [slot] => 3
        )
)
  

в массиве «машина» и «слот» имеют повторяющиеся значения. Я хочу сохранить только одно значение «machine» и «slot», а затем вставить в него значение «lot» дубликатов «machine» и «slot».
Результат, который я хочу, такой:

 Array
(
    [0] => Array
        (
            [MACHINE] => A1
            [LOT] => B1077
            [slot] => 1
        )
    [1] => Array
        (
            [MACHINE] => A2
            [LOT] => B0229           
            [slot] => 2
            [Duplicate] => B0132, B3967
        )   
    [2] => Array
        (
            [MACHINE] => A3
            [LOT] => B2644
            [slot] => 3
        )
)
  

Я пробовал это, чтобы удалить повторяющееся значение, но понятия не имею, как получить желаемый результат.

 $temp = array();
foreach ($array as $v) {
    if (!isset($temp[$v['MACHINE']]))
        $temp[$v['MACHINE']] = $v;
}
$result = array_values($temp);
 echo '<pre>', print_r($result, true), '</pre>';
  

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

1. Как только вы достигнете большого объема данных, то, что вы пытаетесь сделать, будет медленным и недостижимым. Ваша структура данных не адаптирована к этому. Вместо этого индексируйте по ключу, а не по итерации. Или используйте базу данных и структуры запросов.

2. @NVRM спасибо за ваше предложение, хотя это для небольшого объема данных, но я рад узнать больше о навыках программирования. Не могли бы вы, пожалуйста, объяснить подробнее или привести пример «Вместо индекса по ключу, а не по итерации».? Я новичок в программировании.

Ответ №1:

Вы на правильном пути с вашим кодом, вам просто нужно

  • учитывайте slot при создании ключа для $temp ; и
  • добавляйте Duplicate запись, когда она встречается

Например:

 $temp = array();
foreach ($array as $v) {
    $key = $v['MACHINE'] . '#' . $v['slot'];
    if (!isset($temp[$key])) {
        $temp[$key] = $v;
    }
    else {
        $temp[$key]['Duplicate'][] = $v['LOT'];
    }
}
foreach ($temp as amp;$v) {
    if (isset($v['Duplicate'])) $v['Duplicate'] = implode(', ', $v['Duplicate']);
}
$result = array_values($temp);
print_r($result);
  

Я поместил повторяющиеся значения в массив, а затем использовал implode во втором цикле, чтобы создать строку, разделенную запятыми, в желаемом выводе. Возможно, вы обнаружите, что массив на самом деле более полезен, и в этом случае вы можете пропустить второй цикл. Вы также можете выполнить конкатенацию строк «на лету» в цикле, если вы замените

 $temp[$key]['Duplicate'][] = $v['LOT'];
  

с

 $temp[$key]['Duplicate'] = isset($temp[$key]['Duplicate']) ? $temp[$key]['Duplicate'] . ',' . $v['LOT'] : $v['LOT'];
  

Вывод:

 Array
(
    [0] => Array
        (
            [MACHINE] => A1
            [LOT] => B1077
            [slot] => 1
        )
    [1] => Array
        (
            [MACHINE] => A2
            [LOT] => B0229
            [slot] => 2
            [Duplicate] => B0132, B3967
        )
    [2] => Array
        (
            [MACHINE] => A3
            [LOT] => B2644
            [slot] => 3
        )
)
  

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

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

1. Спасибо за быстрый ответ, код понятен и прост в освоении.

Ответ №2:

Вы могли бы использовать тот факт, что массивы в PHP можно использовать как хэш-карты, с которыми вы, возможно, знакомы из других языков программирования:

 <?php

function condense_duplicates($arrays) {
  $machine_slot_map = array();
  
  foreach ($arrays as $arr) {
    $machine_slot_key = "{$arr['MACHINE']}_{$arr['slot']}";
    if (array_key_exists($machine_slot_key, $machine_slot_map)) {
      $lot = $arr['LOT'];
      if (array_key_exists('Duplicate', $machine_slot_map[$machine_slot_key])) {
        $curr_duplicates = $machine_slot_map[$machine_slot_key]['Duplicate'];
        $machine_slot_map[$machine_slot_key]['Duplicate'] = "{$curr_duplicates}, {$lot}";
      } else {
        $machine_slot_map[$machine_slot_key]['Duplicate'] = $lot;
      }
    } else {
      $machine_slot_map[$machine_slot_key] = $arr;
    }
  }

  return array_values($machine_slot_map);
}

$arrays = array (
  array('MACHINE' => 'A1',
        'LOT' => 'B1077',
        'slot' => 1),
  array('MACHINE' => 'A2',
        'LOT' => 'B0229',
        'slot' => 2),
  array('MACHINE' => 'A2',
        'LOT' => 'B0132',
        'slot' => 2),
  array('MACHINE' => 'A2',
        'LOT' => 'B3967',
        'slot' => 2),
  array('MACHINE' => 'A3',
        'LOT' => 'B2644',
        'slot' => 3)
);

// echo 'Before:', PHP_EOL;
// print_r($arrays);

$arrays_with_condensed_duplicates = condense_duplicates($arrays);

// echo 'After:', PHP_EOL;
print_r($arrays_with_condensed_duplicates);
  

Вывод:

 Array
(
    [0] => Array
        (
            [MACHINE] => A1
            [LOT] => B1077
            [slot] => 1
        )

    [1] => Array
        (
            [MACHINE] => A2
            [LOT] => B0229
            [slot] => 2
            [Duplicate] => B0132, B3967
        )

    [2] => Array
        (
            [MACHINE] => A3
            [LOT] => B2644
            [slot] => 3
        )

)
  

Демонстрация на repl.it

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