Подтвердить что ты не робот

Группа php array

У меня есть следующий массив

Array
(
    [0] => Array
        (
            [id] => 96
            [shipping_no] => 212755-1
            [part_no] => reterty
            [description] => tyrfyt
            [packaging_type] => PC
        )

    [1] => Array
        (
            [id] => 96
            [shipping_no] => 212755-1
            [part_no] => dftgtryh
            [description] => dfhgfyh
            [packaging_type] => PC
        )

    [2] => Array
        (
            [id] => 97
            [shipping_no] => 212755-2
            [part_no] => ZeoDark
            [description] => s%c%s%c%s
            [packaging_type] => PC
        )

)

Как я могу группировать массив с помощью id? Существуют ли какие-либо встроенные функции php для этого?

Если я foreach выше, то я получу дубликат, как я могу избежать этого?

В приведенном выше примере id имеется 2 элемента, поэтому его необходимо находиться внутри id.

РЕДАКТИРОВАТЬ: ВСЕ РАБОТЫ ТЯЖЕСТИ: НО ЕСТЬ ЛИ КАКИЕ-ЛИБО ПУТЕМ, ЧТОБЫ ДОСТИГНУТЬ ОДИН САМЫЙ ОДИН ФОРЕКС?

4b9b3361

Ответ 1

Нет родного, просто используйте цикл.

$result = array();
foreach ($data as $element) {
    $result[$element['id']][] = $element;
}

Ответ 2

Вы можете попробовать следующее:

$group = array();

foreach ( $array as $value ) {
    $group[$value['id']][] = $value;
}

var_dump($group);

Вывод:

array
  96 => 
    array
      0 => 
        array
          'id' => int 96
          'shipping_no' => string '212755-1' (length=8)
          'part_no' => string 'reterty' (length=7)
          'description' => string 'tyrfyt' (length=6)
          'packaging_type' => string 'PC' (length=2)
      1 => 
        array
          'id' => int 96
          'shipping_no' => string '212755-1' (length=8)
          'part_no' => string 'dftgtryh' (length=8)
          'description' => string 'dfhgfyh' (length=7)
          'packaging_type' => string 'PC' (length=2)
  97 => 
    array
      0 => 
        array
          'id' => int 97
          'shipping_no' => string '212755-2' (length=8)
          'part_no' => string 'ZeoDark' (length=7)
          'description' => string 's%c%s%c%s' (length=9)
          'packaging_type' => string 'PC' (length=2)

Ответ 3

Я просто бросил это вместе, вдохновленный .NET LINQ

<?php

// callable type hint may be "closure" type hint instead, depending on php version
function array_group_by(array $arr, callable $key_selector) {
  $result = array();
  foreach ($arr as $i) {
    $key = call_user_func($key_selector, $i);
    $result[$key][] = $i;
  }  
  return $result;
}

 $data = array(
        array(1, "Andy", "PHP"),
        array(1, "Andy", "C#"),
        array(2, "Josh", "C#"),
        array(2, "Josh", "ASP"),
        array(1, "Andy", "SQL"),
        array(3, "Steve", "SQL"),
    );

$grouped = array_group_by($data, function($i){  return $i[0]; });

var_dump($grouped);

?>

И ты получишь

array(3) {
  [1]=>
  array(3) {
    [0]=>
    array(3) {
      [0]=>
      int(1)
      [1]=>
      string(4) "Andy"
      [2]=>
      string(3) "PHP"
    }
    [1]=>
    array(3) {
      [0]=>
      int(1)
      [1]=>
      string(4) "Andy"
      [2]=>
      string(2) "C#"
    }
    [2]=>
    array(3) {
      [0]=>
      int(1)
      [1]=>
      string(4) "Andy"
      [2]=>
      string(3) "SQL"
    }
  }
  [2]=>
  array(2) {
    [0]=>
    array(3) {
      [0]=>
      int(2)
      [1]=>
      string(4) "Josh"
      [2]=>
      string(2) "C#"
    }
    [1]=>
    array(3) {
      [0]=>
      int(2)
      [1]=>
      string(4) "Josh"
      [2]=>
      string(3) "ASP"
    }
  }
  [3]=>
  array(1) {
    [0]=>
    array(3) {
      [0]=>
      int(3)
      [1]=>
      string(5) "Steve"
      [2]=>
      string(3) "SQL"
    }
  }
}

Ответ 4

В более функциональном стиле программирования вы можете использовать array_reduce

$groupedById = array_reduce($data, function (array $accumulator, array $element) {
  $accumulator[$element['id']][] = $element;

  return $accumulator;
}, []);

Ответ 5

Мне тоже нужна была такая функция. Я создал этот, вы передаете, какой столбец вы хотите группировать:

function array_group(array $data, $by_column)
{
    $result = [];

    foreach ($data as $item) {
        $column = $item[$by_column];
        unset($item[$by_column]);
        if (isset($result[$column])) {
            $result[$column][] = $item;
        } else {
            $result[$column] = array($item);
        }
    }

    return $result;
}

Ответ 6

for($i = 0 ; $i < count($arr)  ; $i++ )
{
    $tmpArr[$arr[$i]['id']] = $arr[$i]['id'];
}
$vmpArr = array_keys($tmpArr);
print_r($vmpArr);

Ответ 7

Эта функция array_group_by обеспечивает то, что вы ищете:

$grouped = array_group_by($arr, 'id');

Он даже поддерживает многоуровневые группировки:

$grouped = array_group_by($arr, 'id', 'part_no');

Ответ 8

1. GROUP BY один ключ

Эта функция работает как GROUP BY для массива, но с одним важным ограничением: возможна только одна группировка "столбец" ($identifier).

function arrayUniqueByIdentifier(array $array, string $identifier)
{
    $ids = array_column($array, $identifier);
    $ids = array_unique($ids);
    $array = array_filter($array,
        function ($key, $value) use($ids) {
            return in_array($value, array_keys($ids));
        }, ARRAY_FILTER_USE_BOTH);
    return $array;
}

2. Обнаружение уникальных строк для таблицы (двухмерный массив)

Эта функция предназначена для фильтрации "строк". Если мы говорим, что двумерный массив является таблицей, то каждый его элемент представляет собой строку. Таким образом, мы можем удалить дублированные строки с помощью этой функции. Две строки (элементы первого измерения) равны, если все их столбцы (элементы второго измерения) равны. Для сравнения значений столбца применяется: Если значение имеет простой type, само значение будет использоваться при сравнении; в противном случае его тип (array, object, resource, unknown type) будет использоваться.

Стратегия проста: сделать из исходного массива мелким массивом, где элементы implode d "столбцы" исходного массива; затем примените к нему array_unique(...); и в качестве последнего используют обнаруженные идентификаторы для фильтрации исходного массива.

function arrayUniqueByRow(array $table = [], string $implodeSeparator)
{
    $elementStrings = [];
    foreach ($table as $row) {
        // To avoid notices like "Array to string conversion".
        $elementPreparedForImplode = array_map(
            function ($field) {
                $valueType = gettype($field);
                $simpleTypes = ['boolean', 'integer', 'double', 'float', 'string', 'NULL'];
                $field = in_array($valueType, $simpleTypes) ? $field : $valueType;
                return $field;
            }, $row
        );
        $elementStrings[] = implode($implodeSeparator, $elementPreparedForImplode);
    }
    $elementStringsUnique = array_unique($elementStrings);
    $table = array_intersect_key($table, $elementStringsUnique);
    return $table;
}

Также возможно улучшить сравнение, обнаружив класс значений столбца, если его тип object.

$implodeSeparator должен быть более или менее сложным, z.B. spl_object_hash($this).


3. Обнаружение строк с уникальными столбцами идентификатора для таблицы (двухмерный массив)

Это решение зависит от второго. Теперь полный "ряд" не обязательно должен быть уникальным. Две "строки" (элементы первого измерения) теперь равны, если все соответствующие "поля" (элементы второго измерения) одной "строки" равны соответствующим "полям" (элементы с одним и тем же ключом).

"Соответствующие" "поля" - это "поля" (элементы второго измерения), которые имеют ключ, равный одному из элементов прошедших "идентификаторов".

function arrayUniqueByMultipleIdentifiers(array $table, array $identifiers, string $implodeSeparator = null)
{
    $arrayForMakingUniqueByRow = $removeArrayColumns($table, $identifiers, true);
    $arrayUniqueByRow = $arrayUniqueByRow($arrayForMakingUniqueByRow, $implodeSeparator);
    $arrayUniqueByMultipleIdentifiers = array_intersect_key($table, $arrayUniqueByRow);
    return $arrayUniqueByMultipleIdentifiers;
}

function removeArrayColumns(array $table, array $columnNames, bool $isWhitelist = false)
{
    foreach ($table as $rowKey => $row) {
        if (is_array($row)) {
            if ($isWhitelist) {
                foreach ($row as $fieldName => $fieldValue) {
                    if (!in_array($fieldName, $columnNames)) {
                        unset($table[$rowKey][$fieldName]);
                    }
                }
            } else {
                foreach ($row as $fieldName => $fieldValue) {
                    if (in_array($fieldName, $columnNames)) {
                        unset($table[$rowKey][$fieldName]);
                    }
                }
            }
        }
    }
    return $table;
}

Ответ 9

Расширение на @baba ответ, который мне нравится, но создает более сложный трехуровневый многомерный массив (массив (массив)):

$group = array();
 foreach ( $array as $value ) {
   $group[$value['id']][] = $value; 
 }

// output only data from id 96
foreach ($group as $key=>$value) { //outer loop
 foreach ($value as $k=>$v){ //inner loop
  if($key==96){ //if outer loop is equal to 96 (could be variable)
   for ($i=0;$i<count($k);$i++){ //iterate over the inner loop
        printf($key.' has a part no. of '.$v['part_no'].' and shipping no. of '.$v['shipping_no'].'<br>');
   }
 }
}
 }

Будет выводиться:

96 имеет номер детали. ретрансляции и отгрузочного номера 212755-1

96 имеет номер детали. dftgtryh и номер доставки 212755-1

Ответ 10

Это тривиально для LINQ, который реализован в PHP в нескольких библиотеках, включая YaLinqo *. Он позволяет выполнять SQL-запросы на массивы и объекты. Функция groubBy предназначена специально для группировки, вам просто нужно указать поле, которое вы хотите сгруппировать:

$grouped_array = from($array)->groupBy('$v["id"]')->toArray();

Где '$v["id"]' является сокращением для function ($v) { return $v["id"]; }, которое поддерживает эта библиотека.

Результат будет точно таким же, как в принятом ответе, с меньшим количеством кода.

*, разработанный мной

Ответ 11

$arr = array();

foreach($old_arr as $key => $item)
{
   $arr[$item['id']][$key] = $item;
}

ksort($arr, SORT_NUMERIC);

Ответ 12

Это должно группировать ассоциативный массив Ejm Group По странам

function getGroupedArray($array, $keyFieldsToGroup) {   
    $newArray = array();

    foreach ($array as $record) 
        $newArray = getRecursiveArray($record, $keyFieldsToGroup, $newArray);

    return $newArray;
}
function getRecursiveArray($itemArray, $keys, $newArray) {
    if (count($keys) > 1) 
        $newArray[$itemArray[$keys[0]]] = getRecursiveArray($itemArray,    array_splice($keys, 1), $newArray[$itemArray[$keys[0]]]);
    else
        $newArray[$itemArray[$keys[0]]][] = $itemArray;

    return $newArray;
}

$countries = array(array('Country'=>'USA', 'State'=>'California'),
                   array('Country'=>'USA', 'State'=>'Alabama'),
                   array('Country'=>'BRA', 'State'=>'Sao Paulo'));

$grouped = getGroupedArray($countries, array('Country'));

Ответ 13

Отметьте indexed функцию Nspl

use function \nspl\a\indexed;
$grouped = indexed($data, 'id');

Ответ 14

function array_group_by($arr, array $keys) {

if (!is_array($arr)) {
    trigger_error('array_group_by(): The first argument should be an array', E_USER_ERROR);
}
if (count($keys)==0) {
    trigger_error('array_group_by(): The Second argument Array can not be empty', E_USER_ERROR);
}

// Load the new array, splitting by the target key
$grouped = [];
foreach ($arr as $value) {
    $grouped[$value[$keys[0]]][] = $value;
}

// Recursively build a nested grouping if more parameters are supplied
// Each grouped array value is grouped according to the next sequential key
if (count($keys) > 1) {
        foreach ($grouped as $key => $value) {
       $parms = array_merge([$value], [array_slice($keys, 1,count($keys))]);
       $grouped[$key] = call_user_func_array('array_group_by', $parms);

    }
}
return $grouped;

}

Ответ 15

$ arr = Data Araay;

$ fldName = Группировать по имени столбца;

function array_group_by( $arr, $fldName) {
    $groups = array();
    foreach ($arr as $rec) {
        $groups[$rec[$fldName]] = $rec;
    }
    return $groups;
}

function object_group_by( $obj, $fldName) {
    $groups = array();
    foreach ($obj as $rec) {
        $groups[$rec->$fldName] = $rec;
    }
    return $groups;
}

Ответ 16

function groupeByPHP($array,$indexUnique,$assoGroup,$keepInOne){
$retour = array();
$id = $array[0][$indexUnique];
foreach ($keepInOne as $keep){
    $retour[$id][$keep] = $array[0][$keep];
}
foreach ($assoGroup as $cle=>$arrayKey){
    $arrayGrouped = array();
        foreach ($array as $data){
            if($data[$indexUnique] != $id){
                $id = $data[$indexUnique];
                foreach ($keepInOne as $keep){
                    $retour[$id][$keep] = $data[$keep];
                }
            }
            foreach ($arrayKey as $val){
                $arrayGrouped[$val] = $data[$val];
            }
            $retour[$id][$cle][] = $arrayGrouped;
            $retour[$id][$cle] = array_unique($retour[$id][$cle],SORT_REGULAR);
        }
}
return  $retour;
}

Попробуйте эту функцию

groupeByPHP($yourArray,'id',array('desc'=>array('part_no','packaging_type')),array('id','shipping_no')) 

Ответ 17

Рекурсивная функция группировки 2-мерного массива по ключам от первого до последнего

Входные данные:

$arr = array(
    '0' => array(
        'key0' => 'value0',
        'key1' => 'value1',
        'key2' => 'value02',
    ),
    '2' => array(
        'key0' => 'value0',
        'key1' => 'value1',
        'key2' => 'value12',
    ),
    '3' => array(
        'key0' => 'value0',
        'key1' => 'value3',
        'key2' => 'value22',
    ),
);
$keys = array('key0', 'key1', 'key2');

Выход:

$arr = array(
    'value0' => array(
        'value1 => array(
            'value02' => null,
            'value12' => null,
        ),
        'value3' => 'value22',
    ),
);

Код:

function array_group_by_keys(&$arr, $keys) {

if (count($arr) < 2){
    $arr = array_shift($arr[0]);
    return;
}

foreach ($arr as $k => $item) {
    $fvalue = array_shift($item);
    $arr[$fvalue][] = $item;
    unset($arr[$k]);
}

array_shift($keys);
foreach ($arr as &$sub_arr) {
    array_group_by_keys($sub_arr, $keys);
}

}