Как показать дубликаты данных в многомерном массиве с помощью PHP - PullRequest
0 голосов
/ 13 февраля 2019

Я использую Spout Excel Reader для чтения файлов Excel из PHP-кода и сохранения в многомерном массиве в переменной PHP. Массив выглядит следующим образом

$array = [
[
    'id[0]' => 'BX-78',
    'Name[0]' => 'XXX',
    'Address[0]' => 'YUUSATD'
],
[
    'id[1]' => 'BX-79',
    'Name[1]' => 'YYY',
    'Address[1]' => 'DHJSHDJGY'
],
[
    'id[2]' => 'BX-80',
    'Name[2]' => 'ZZZ',
    'Address[2]' => 'DDSDSDA'
]
[
    'id[3]' => 'BX-78',
    'Name[3]' => 'AAA',
    'Address[3]' => 'FSDSDS'
][
    'id[4]' => 'BX-81',
    'Name[4]' => 'XXX',
    'Address[4]' => 'DSDSDSD'
]];

Теперь я хочу показать дублирующиеся данные из массива выше, используядве клавиши ['id'] и ['name'], если идентификаторы повторяются, отображаются как дубликаты данных,

  • Если имена повторяются, показывают, что строки как дубликаты данных, если оба являются дубликатами, показывают как снова дублирующиеся строки
  • В противном случае это уникальная строка.

Я пытался использовать сортировку многомерных массивов, но для сопоставления данных в строках используется только один ключ.

foreach ($arrExcelData as $v) {
   if (isset($arrExcelData[$v[0]])) {
       // found duplicate
       continue;
    }
    // remember unique item
    $arrExcelData3[$v[0]] = $v;
}

// if you need a zero-based array, otheriwse work with $_data
$arrExcelData2 = array_values($arrExcelData3);

Отредактировано: ожидаемый результат вывода:

Соответствующие строки:

Id       Name    Address
-------------------------
BX-78    XXX     YUUSATD
BX-78    AAA     DDSDSDA
BX-81    XXX     DSDSDSD`

Ответы [ 4 ]

0 голосов
/ 14 февраля 2019

Если кто-то из вас ищет уникальные значения по ключу.

function unique_multidim_array($array, $key) {
                    $temp_array = array();
                    $i = 0;
                    $key_array = array();
                    foreach($array as $val) {
                        if (!in_array($val[$key], $key_array)) {
                            $key_array[$i] = $val[$key];
                            $temp_array[$i] = $val;
                        }
                        $i++;
                    }
                    return $temp_array;
            }
  • Эта функция просто принимает многомерный массив и значение ключа нужного вам поля.

  • Затем принимает значение заданного массива один за другим (меньшие массивы).

  • Затем обходит данный массив и проверяет, совпадает ли полученная пара ключ-значение с заданным ключом.

  • После этого, если взятая пара ключ-значение совпадает с заданной функцией ключа, просто вставляет меньший массив во временный массив (массив с уникальными значениями).

  • Не забывайте увеличивать индексы массивов ($ i).

  • Затем возвращайте полученный массив (с уникальными значениями) после завершения работы функции.

0 голосов
/ 13 февраля 2019

Вы можете сделать что-то вроде этого:

$dupes = [];
$current = [];

foreach ($array as $index => $entry) {
  $idKey = "id[$index]";
  $nameKey = "Name[$index]";
  if (array_key_exists($entry[$idKey], $current)) {
    $dupes[] = [$entry, $current[$entry[$idKey]]];
  }
  elseif (array_key_exists($entry[$nameKey], $current)) {
    $dupes[] = [$entry, $current[$entry[$nameKey]]];
  }
  else {
    $current[$entry[$idKey]] = $current[$entry[$nameKey]] = $entry;
  }
}

print_r($dupes);

В результате получается массив, содержащий каждый набор дубликатов (массив массивов):

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [id[3]] => BX-78
                    [Name[3]] => AAA
                    [Address[3]] => FSDSDS
                )

            [1] => Array
                (
                    [id[0]] => BX-78
                    [Name[0]] => XXX
                    [Address[0]] => YUUSATD
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [id[4]] => BX-81
                    [Name[4]] => XXX
                    [Address[4]] => DSDSDSD
                )

            [1] => Array
                (
                    [id[0]] => BX-78
                    [Name[0]] => XXX
                    [Address[0]] => YUUSATD
                )

        )

)

Демонстрация здесь:https://3v4l.org/JAtNU

0 голосов
/ 13 февраля 2019

Если вы хотите перечислить повторяющиеся значения, я думаю, что адрес второго совпадения должен быть FSDSDS, поскольку нет элемента с именем AAA и значением DDSDSDA:

BX-78    AAA     FSDSDS

Если это так, то вы могли бы сначала использовать двойной foreach, чтобы пометить массивы, которые содержат повторяющиеся идентификатор или имя, например, добавив свойство с именами id и name, за исключением случаев, когда сам массив находится ввторой цикл.

После этого цикла вы можете сказать, какие массивы являются дублирующими.Вместо использования соответствующего индекса 0, как в id[0], я использовал reset и next, чтобы он не привязывался к этим индексам.

Чтобы получить отфильтрованный результат, вы можете использовать array_reduce дляпроверьте ключи массива и удалите их.

Например:

foreach ($array as $index => $a) {
    foreach ($array as $v) {
        if ($v === $a) continue;
        if (reset($v) === reset($a)) $array[$index]["id"] = "duplicate";
        if (next($v) === next($a)) $array[$index]["name"] = "duplicate";
    }
}

$array = array_reduce($array, function($carry, $item) {
    if (array_key_exists("id", $item) || array_key_exists("name", $item)) {
        unset($item["id"], $item["name"]);
        $carry[] = $item;
    }
    return $carry;
}, []);

print_r($array);

Результат

Array
(
    [0] => Array
        (
            [id[0]] => BX-78
            [Name[0]] => XXX
            [Address[0]] => YUUSATD
        )

    [1] => Array
        (
            [id[3]] => BX-78
            [Name[3]] => AAA
            [Address[3]] => FSDSDS
        )

    [2] => Array
        (
            [id[4]] => BX-81
            [Name[4]] => XXX
            [Address[4]] => DSDSDSD
        )

)

См. php demo

0 голосов
/ 13 февраля 2019

У меня очень прагматичный подход:

$spout_output = [
[
    'id[0]' => 'BX-78',
    'Name[0]' => 'XXX',
    'Address[0]' => 'YUUSATD'
],
[
    'id[1]' => 'BX-79',
    'Name[1]' => 'YYY',
    'Address[1]' => 'DHJSHDJGY'
],
[
    'id[2]' => 'BX-80',
    'Name[2]' => 'ZZZ',
    'Address[2]' => 'DDSDSDA'
],
[
    'id[3]' => 'BX-78',
    'Name[3]' => 'AAA',
    'Address[3]' => 'FSDSDS'
],
[
    'id[4]' => 'BX-81',
    'Name[4]' => 'XXX',
    'Address[4]' => 'DSDSDSD'
]];

// store id to row, and name to row mappings.
// id and name will be keys, value will be an array of indexes of the array $spout_output
$id_to_rows = array();
$name_to_rows = array();

$duplicate_ids = array();
$duplicate_names = array();

foreach($spout_output as $row => $data)
{
    $key_id = 'id['.$row.']';
    $key_name = 'Name['.$row.']';

    if(!isset($data[$key_id]))
        continue;

    $value_id = $data[$key_id];
    $value_name = $data[$key_name];

    if(!isset($id_to_rows[$value_id]))
    {
        $id_to_rows[$value_id] = array();
    }
    else
    {
        if(!isset($duplicate_ids[$value_id]))
        {
            $duplicate_ids[$value_id] = $id_to_rows[$value_id];
        }

        $duplicate_ids[$value_id][] = $row;
    }

    if(!isset($name_to_rows[$value_name]))
    {
        $name_to_rows[$value_name] = array();
    }
    else
    {
        if(!isset($duplicate_names[$value_name]))
        {
            $duplicate_names[$value_name] = $name_to_rows[$value_name];
        }

        $duplicate_names[$value_name][] = $row;
    }

    $id_to_rows[$value_id][] = $row;
    $name_to_rows[$value_name][] = $row;
}

echo 'Duplicates:';
echo '<br>';
$shown_rows = array();
foreach($duplicate_ids as $id => $rows)
{
    foreach($rows as $nr)
    {
        echo $id . '|' . $spout_output[$nr]['Name['.$nr.']'] . '|' . $spout_output[$nr]['Address['.$nr.']'];
        echo '<br>';
        $shown_rows[] = $nr;
    }
}

foreach($duplicate_names as $name => $rows)
{
    foreach($rows as $nr)
    {
        // if already shown above, skip this row
        if(in_array($nr, $shown_rows))
            continue;

        echo $spout_output[$nr]['id['.$nr.']'] . '|' . $spout_output[$nr]['Name['.$nr.']'] . '|' . $spout_output[$nr]['Address['.$nr.']'];
        echo '<br>';
        $shown_rows[] = $nr;
    }
}

Выходы:

Duplicates:
BX-78|XXX|YUUSATD
BX-78|AAA|FSDSDS
BX-81|XXX|DSDSDSD

Я думаю, что ваш "требуемый вывод" содержит ошибку в адресе?В любом случае, с моим кодом выше, я думаю, у вас будет достаточно отображенных данных для получения желаемого результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...