Сплит и группировать массив по ключам - PullRequest
0 голосов
/ 28 августа 2018

Хорошо, я немного искал и не нашел ответа, так что я собираюсь дать этому шанс.

У меня есть JSON-файл, который может выдать следующую информацию:

[
    {
        "Contact name(s)": "Person 1, Person 2",
        "Contact title(s)": "Head Comacho, Other Guy",
        "Contact email(s)": "email1@email.net, email@email.com",
        "Contact phone": "123-456-7890, 789-456-1230",
    },
    {   
        "Contact name(s)": "Some Dude",
        "Contact title(s)": "Cool Title",
        "Contact email(s)": "things@email.com",
        "Contact phone": "555-555-5555",
    },
        "Contact name(s)": "",
        "Contact title(s)": "",
        "Contact email(s)": "",
        "Contact phone": "",
    }
]

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

Array
(
    [0] => Array
        (
            [contact_name] => Person 1
            [contact_title] => Head Comacho
            [contact_email] => email1@email.net
            [contact_phone] => 123-456-7890
        )

    [1] => Array
        (
            [contact_name] => Person 2
            [contact_title] => Other Title
            [contact_email] => email@email.com
            [contact_phone] => 789-456-1230
        )
)
Array
(
    [0] => Array
        (
            [contact_name] => Some Dude
            [contact_title] => Cool Title
            [contact_email] => things@email.com
            [contact_phone] => 555-555-5555
        )
)
Array
(
    [0] => Array
        (
            [contact_name] => 
            [contact_title] => 
            [contact_email] => 
            [contact_phone] => 
        )
)

Мне удалось преобразовать данные в их собственные массивы, выглядя так:

Array
(
    [contact_name] => Array
        (
            [0] => Person 1
            [1] => Person 2
        )

    [contact_title] => Array
        (
            [0] => Head Comacho
            [1] => Other Guy
        )

    [contact_email] => Array
        (
            [0] => email1@email.net
            [1] => email@email.com
        )

    [contact_phone] => Array
        (
            [0] => 123-456-7890
            [1] => 789-456-1230
        )

)

Array
(
 .....etc
)

Как бы я понял, как в первом примере?

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

Ответы [ 4 ]

0 голосов
/ 29 августа 2018

Если бы это был мой проект, это то, что я бы сделал и почему ...

  1. Вам необходимо хранить каждое подмножество данных отдельно друг от друга, поэтому используйте $temp в качестве временного хранилища между итерациями внешнего цикла. Временный массив должен быть сброшен в начале каждого нового $set, а данные временного массива должны быть перенесены в массив $result для поддержки индексов исходного набора.
  2. explode() лучше всего указывать в качестве разделителя «запятая» - это исключает необходимость вызывать какие-либо дополнительные функции, чтобы убрать оставшиеся пробелы.
  3. Поскольку ваши старые и новые ключи известны и статичны, жесткое кодирование ассоциативного массива «перевода» избавит от большого количества повторных вызовов функций и в значительной степени сократит разрастание кода. Я также утверждаю, что это дает вам более простой контроль над подготовкой ключа, и будущие разработчики быстро смогут понять, что делает ваш код.

Код: ( Демо )

$json = '[
    {"Contact name(s)": "Person 1, Person 2", "Contact title(s)": "Head Comacho, Other Guy", "Contact email(s)": "email1@email.net, email@email.com", "Contact phone": "123-456-7890, 789-456-1230"},
    {"Contact name(s)": "Some Dude", "Contact title(s)": "Cool Title", "Contact email(s)": "things@email.com", "Contact phone": "555-555-5555"},
    {"Contact name(s)": "", "Contact title(s)": "", "Contact email(s)": "", "Contact phone": ""}
]';
$array = json_decode($json, true);

$trans = [
    "Contact name(s)" => "contact_name",
    "Contact title(s)" => "contact_title",
    "Contact email(s)" => "contact_email",
    "Contact phone" => "contact_phone"    
];

foreach ($array as $set) {
    $temp = [];
    foreach ($set as $key => $data) {
        foreach (explode(', ', $data) as $index => $value) {
            $temp[$index][$trans[$key]] = $value;     
        }
    }
    $result[] = $temp;
}
var_export($result);

Выход:

array (
  0 => 
  array (
    0 => 
    array (
      'contact_name' => 'Person 1',
      'contact_title' => 'Head Comacho',
      'contact_email' => 'email1@email.net',
      'contact_phone' => '123-456-7890',
    ),
    1 => 
    array (
      'contact_name' => 'Person 2',
      'contact_title' => 'Other Guy',
      'contact_email' => 'email@email.com',
      'contact_phone' => '789-456-1230',
    ),
  ),
  1 => 
  array (
    0 => 
    array (
      'contact_name' => 'Some Dude',
      'contact_title' => 'Cool Title',
      'contact_email' => 'things@email.com',
      'contact_phone' => '555-555-5555',
    ),
  ),
  2 => 
  array (
    0 => 
    array (
      'contact_name' => '',
      'contact_title' => '',
      'contact_email' => '',
      'contact_phone' => '',
    ),
  ),
)

Вы обнаружите, что это решение не просто лаконично, точно и легко читается; это также очень эффективно, потому что во всем процессе есть только один повторный вызов функции (explode()).

0 голосов
/ 28 августа 2018

Я думаю, что этот скрипт будет делать то, что вы хотите. Я создал функцию split_contacts, которая принимает каждую запись в декодированном массиве и разбивает значения (например, "Person 1, Person 2" => ["Person 1", "Person 2"]) на массивы, проиндексированные ключами объекта, что preg_replace массируются в желаемую форму (например, "Contact name(s)" => "contact_name"). Обратите внимание, что, возможно, было возможно использовать str_replace вместо preg_replace, но я хотел сохранить гибкость кода с точки зрения формата значений вашего ключа.

$json = '[
    {
        "Contact name(s)": "Person 1, Person 2",
        "Contact title(s)": "Head Comacho, Other Guy",
        "Contact email(s)": "email1@email.net, email@email.com",
        "Contact phone": "123-456-7890, 789-456-1230"
    },
    {   
        "Contact name(s)": "Some Dude",
        "Contact title(s)": "Cool Title",
        "Contact email(s)": "things@email.com",
        "Contact phone": "555-555-5555"
    },
    {
        "Contact name(s)": "",
        "Contact title(s)": "",
        "Contact email(s)": "",
        "Contact phone": ""
    }
]';
$arr = json_decode($json, true);

function split_contact($contact) {
    $contacts = array();
    foreach ($contact as $key => $values) {
        $key = strtolower(preg_replace(array('/\(s\)$/', '/\s+/'), array('', '_'), $key));
        foreach (explode(',', $values) as $index => $value) {
            $contacts[$index][$key] = trim($value);
        }
    }
    return $contacts;
}

$newarr = array();
foreach ($arr as $contact) {
    $newarr[] = split_contact($contact);
}

print_r($newarr);

Выход:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [contact_name] => Person 1
                    [contact_title] => Head Comacho
                    [contact_email] => email1@email.net
                    [contact_phone] => 123-456-7890
                )    
            [1] => Array
                (
                    [contact_name] =>  Person 2
                    [contact_title] =>  Other Guy
                    [contact_email] =>  email@email.com
                    [contact_phone] =>  789-456-1230
                )    
        )    
    [1] => Array
        (
            [0] => Array
                (
                    [contact_name] => Some Dude
                    [contact_title] => Cool Title
                    [contact_email] => things@email.com
                    [contact_phone] => 555-555-5555
                )    
        )    
    [2] => Array
        (
            [0] => Array
                (
                    [contact_name] => 
                    [contact_title] => 
                    [contact_email] => 
                    [contact_phone] => 
                )    
        )    
)
0 голосов
/ 28 августа 2018

Я пришел к этому решению:

$arr = '[
    {
        "Contact name(s)": "Person 1, Person 2",
        "Contact title(s)": "Head Comacho, Other Guy",
        "Contact email(s)": "email1@email.net, email@email.com",
        "Contact phone": "123-456-7890, 789-456-1230"
    },
    {   
        "Contact name(s)": "Some Dude",
        "Contact title(s)": "Cool Title",
        "Contact email(s)": "things@email.com",
        "Contact phone": "555-555-5555"
    },
    {
        "Contact name(s)": "",
        "Contact title(s)": "",
        "Contact email(s)": "",
        "Contact phone": ""
    }
]';

$arr = json_decode($arr, true);

foreach ($arr as $row) {

    list($m_name, $m_title, $m_email, $m_phone) =
    [explode(',', $row["Contact name(s)"]),explode(',', $row["Contact title(s)"]),
     explode(',', $row["Contact email(s)"]),explode(',', $row["Contact phone"])];

    foreach (array_keys($m_name) as $per)
        $result[] = ['name' => $m_name[$per],'title' => $m_title[$per],
                     'email' => $m_email[$per],'phone' => $m_phone[$per]];
}

var_dump($result);
0 голосов
/ 28 августа 2018

Если вы можете убедиться, что объект json для нескольких людей всегда содержит одинаковое количество элементов, то вы можете сделать что-то подобное:

<?php

$json = '[
    {"Contact name(s)": "Person 1, Person 2", "Contact title(s)": "Head Comacho, Other Guy", "Contact email(s)": "email1@email.net, email@email.com", "Contact phone": "123-456-7890, 789-456-1230"},
    {"Contact name(s)": "Some Dude", "Contact title(s)": "Cool Title", "Contact email(s)": "things@email.com", "Contact phone": "555-555-5555"},
    {"Contact name(s)": "", "Contact title(s)": "", "Contact email(s)": "", "Contact phone": ""}
]';

$jsonA = json_decode($json, true);

$result = [];
$maxLen = 0;
foreach ($jsonA as &$obj) {
    foreach ($obj as $k => $v) {
        if (!isset($result[$k])) $result[$k] = [];
        foreach (explode(',', $v) as $av) $result[$k][] = trim($av);
        $maxLen = max($maxLen, count($result[$k]));
    }
}

$objects = [];
for ($i=0; $i<$maxLen; $i++) {
    $object = [];
    foreach (array_keys($result) as $k) $object[$k] = isset($result[$k][$i]) ? $result[$k][$i] : '';
    $objects[] = $object;
}

echo '<pre>';
print_r($objects);

печатает:

Array
(
    [0] => Array
        (
            [Contact name(s)] => Person 1
            [Contact title(s)] => Head Comacho
            [Contact email(s)] => email1@email.net
            [Contact phone] => 123-456-7890
        )

    [1] => Array
        (
            [Contact name(s)] => Person 2
            [Contact title(s)] => Other Guy
            [Contact email(s)] => email@email.com
            [Contact phone] => 789-456-1230
        )

    [2] => Array
        (
            [Contact name(s)] => Some Dude
            [Contact title(s)] => Cool Title
            [Contact email(s)] => things@email.com
            [Contact phone] => 555-555-5555
        )

    [3] => Array
        (
            [Contact name(s)] => 
            [Contact title(s)] => 
            [Contact email(s)] => 
            [Contact phone] => 
        )

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